Search the Community
Showing results for tags 'script'.
-
Hva skal hentes denne uka er et gjentagende SPM hjemme hos oss. Så jeg fant APPEN "Min renovasjon.". Men en app er jo ikke løsningen på noe. For man vil jo ha denne informasjonen inn i homeseer. MinRenovasjon.vb Sub Main(ByVal parameters As Object) 'Clio75 All Credits to [email protected] 'Inspired and based on Moskus scrip NewsReader.vb Dim DevID As Integer = parameters.ToString.Split("|")(0) Dim KommuneNr As String = parameters.ToString.Split("|")(1) Dim Gatekode As String = parameters.ToString.Split("|")(2) Dim GateNavn As String = parameters.ToString.Split("|")(3) Dim GateNr As String = parameters.ToString.Split("|")(4) 'Sette sammen URL: Dim kommuneURL as string = "kommunenr=" & KommuneNr Dim GateKodeURL as string = "gatekode=" & Gatekode Dim GateNavnURL as string = "gatenavn=" & GateNavn Dim GateNrURL as string = "husnr=" & GateNr Dim url As String = "https://komteksky.norkart.no/komtek.renovasjonwebapi/api/tommekalender/?" & kommuneURL & "&" & GateNavnURL & "&" & GateKodeURL & "&" & GateNrURL 'hs.WriteLog("Soppel Error", "url " & url) Dim source As String = "" Try Using client As New System.Net.WebClient 'Sette Headers client.headers.set("Kommunenr", KommuneNr ) client.headers.set("RenovasjonAppKey", "AE13DEEC-804F-4615-A74E-B4FAC11F0A30") Net.ServicePointManager.SecurityProtocol = Net.SecurityProtocolType.Tls12 client.Encoding = System.Text.Encoding.UTF8 source = client.DownloadString(url) End Using Catch ex As Exception hs.WriteLog("Soppel Error", "Net Feil: " & ex.Message) End Try If source = "" Then hs.WriteLog("soppel Error", "Got no response from url: " & url) Exit Sub End If Try 'Dim json as Newtonsoft.Json.string = Newtonsoft.Json.JsonConvert.DeserializeObject(Of Object)(source) Dim json as Object = Newtonsoft.Json.JsonConvert.DeserializeObject(Of Object)(source) Dim numMembers As Integer = json.Count -1 Dim DeviceText As String = "" For i As Integer = 0 To numMembers Dim output As String = "" Dim output2 As String = "" output = json(i)("FraksjonId") output2 = json(i)("Tommedatoer")(0) & " Neste :" Try output2 &= json(i)("Tommedatoer")(1) Catch ex As Exception output2 &= " -- " End Try Select Case Output Case "1" output = Replace(output, "1", "<b>Restavfall : </b><br>") Case "2" output = Replace(output, "2", "<b>Papiravfall : </b><br>") Case "3" output = Replace(output, "3", "<b>Matavfall : </b> <br>") Case "4" output = Replace(output, "4", "<b>Glass/Metall : </b><br>") Case "5" output = Replace(output, "5", "<b>Drikkekartonger </b><br>") Case "6" output = Replace(output, "6", "<b>Grovavfall : </b><br>") Case "7" output = Replace(output, "7", "<b>Plastavfall : </b><br>") End Select DeviceText &= "" & output & " " & output2 & "<br>" Next hs.SetDeviceString(DevID, DeviceText , True) Catch ex As Exception hs.WriteLog("Soppel Error", "Net Feil: " & ex.Message) End Try End Sub Så en event : Parameters : DevieRef | Kommunenummer | Gatenummer | GataNavn | Husnummer Ser jeg forsatt har manuell trigger i screenshot, men en gang i døgnet burde vel holde i de fleste tilfeller. SOM ga meg denne : Instalering : VeiNummer: For å finne vegnummeret kan du gå inn på https://www.vegvesen.no/vegkart zoom deg inn på vegen din og nærmest mulig huset ditt klikker du på veien, Så finner du de 5 sifferene du trenger(Rødt). Kommune Nummeret var de fire første her i Blått : 0710 HomeSeer trenger en referanse til Newtonsoft.Json.Dll, det kan du sette opp ved å lese under "Installasjon" i denne tråden: https://www.hjemmeautomasjon.no/forums/topic/4338-script-enturvb-få-inn-data-fra-entur/ Takk Til: Dette hadde jeg ikke klart alene. @Moskus skal ha en stor takk for sine delinger av script. Tatt utgangspunktet i hans NewsReader.VB @Marhil Takk for tipset om Min renovasjons app eller hvordan jeg fant Gatenummer Og alle de andre som deler kode og eksempler åpnet på nett
-
Nå kan du endelig få endre trigger-tiden til dine eventer med noen enkle tastetrykk! Det fungerer fint på websiden, HStouch og HS Mobile. Vi har alle eventer som går av på et visst tidspunkt. F.eks. vekkerklokker. Av og til vil man enkelt kunne endre tiden på vekkerklokken uten å måtte navigere til Event-siden og finne selve eventet. Kanskje vil man at ungene skal kunne gjøre det, etc. Med dette scriptet får du en device som dette: ... som lar deg endre klokkeslettet på et event. Her er scriptet (vær nøye med filnavnet, det må være riktig): TimeDevice.vb Public Sub Main(ByVal input As Object) 'Moskus 2019 '----------------------------- 'The Main sub will update 'DeviceRef,NewTime 'Example: 3245,13:00 -> will set device 3245 to 13:00 and the event to trigger at 13:00 '----------------------------- Dim deviceRef As Integer = input.ToString.Split(",")(0) Dim timeString As String = input.ToString.Split(",")(1) Dim _time As TimeSpan = TimeSpan.Parse(timeString) UpdateDeviceAndEvent(deviceRef, _time) End Sub Public Sub CreateDevice(byval input as Object) Dim deviceRef As Integer = hs.NewDeviceRef("Klokkekontroll") Dim dev As Scheduler.Classes.DeviceClass = hs.GetDeviceByRef(deviceRef) dev.Location(hs) = "Klokke" dev.Location2(hs) = "Klokke" dev.Device_Type_String(hs) = "Ditt event her" hs.SaveEventsDevices() AddDeviceButtons(deviceRef) Dim _time As New TimeSpan hs.SetDeviceString(deviceRef, _time.ToString("hh\:mm"), False) hs.SetDeviceValueByRef(deviceRef, _time.TotalMinutes, True) End Sub Public Sub ButtonPress(ByVal input As Object) Dim deviceRef As Integer = input(0) Dim parameter As String = input(1) Dim deviceValue As Integer = hs.DeviceValue(deviceRef) Dim minutesToAdd As Integer = Integer.Parse(parameter) Dim newValue As Integer = deviceValue + minutesToAdd If newValue < 0 Then newValue = 24 * 60 + minutesToAdd If newValue > 24 * 60 Then newValue = minutesToAdd Dim _time As TimeSpan = New TimeSpan(0, newValue, 0) UpdateDeviceAndEvent(deviceRef, _time) End Sub Public Sub UpdateDeviceAndEvent(ByVal deviceRef As Integer, ByVal _time As TimeSpan) hs.SetDeviceString(deviceRef, _time.ToString("hh\:mm"), False) hs.SetDeviceValueByRef(deviceRef, _time.TotalMinutes, True) Dim eventName As String = DirectCast(hs.GetDeviceByRef(deviceRef), Scheduler.Classes.DeviceClass).Device_Type_String(hs) Dim eventRef As String = hs.GetEventRefByName(eventName) hs.EventSetTimeTrigger(eventRef, New Date(1, 1, 1).Add(_time)) hs.SaveEventsDevices() End Sub Public Sub AddDeviceButtons(ByVal device_ref As String) Dim devID As Integer = CInt(device_ref) hs.DeviceScriptButton_DeleteAll(devID) hs.DeviceProperty_dvMISC(device_ref, HomeSeerAPI.Enums.eDeviceProperty.MISC_Set, HomeSeerAPI.Enums.dvMISC.SHOW_VALUES) Try hs.WriteLog("TimeDevice.vb", "Added button 1: " & hs.DeviceScriptButton_AddButton(devID, "+5 min", 5, "TimeDevice.vb", "ButtonPress", "+5", 1, 1, 1)) hs.WriteLog("TimeDevice.vb", "Added button 2: " & hs.DeviceScriptButton_AddButton(devID, "-5 min", -5, "TimeDevice.vb", "ButtonPress", "-5", 1, 2, 1)) hs.WriteLog("TimeDevice.vb", "Added button 3: " & hs.DeviceScriptButton_AddButton(devID, "+15 min", 15, "TimeDevice.vb", "ButtonPress", "+15", 1, 3, 1)) hs.WriteLog("TimeDevice.vb", "Added button 4: " & hs.DeviceScriptButton_AddButton(devID, "-15 min", -15, "TimeDevice.vb", "ButtonPress", "-15", 1, 4, 1)) hs.WriteLog("TimeDevice.vb", "Added button 5: " & hs.DeviceScriptButton_AddButton(devID, "+1 time", 60, "TimeDevice.vb", "ButtonPress", "+60", 2, 1, 1)) hs.WriteLog("TimeDevice.vb", "Added button 6: " & hs.DeviceScriptButton_AddButton(devID, "-1 time", -60, "TimeDevice.vb", "ButtonPress", "-60", 2, 2, 1)) Catch ex As Exception hs.WriteLog("TimeDevice.vb", "Error adding buttons: " & ex.Message) End Try End Sub Du trenger først å lage et event som trigger scriptet med rutinen "CreateDevice", slik: Gå nå til Device Manager-siden. Velg at "Klokke" skal vises, både for "Floor" og "Room". MEN: Du må også huske på å velge ALLE device typer: Da får du opp den nye devicen. Denne kan du navngi og gi plassering akkurat som det passer deg. Så skal vi bestemme hvilket event som skal trigges. Navnet sette vi som en "Device Type String" under Advanced-taben. Merk at hele navnet skal brukes, og at det er "Gruppe" + mellomrom + "Event navn". La oss si at jeg vil trigge et test-event som jeg har navngitt "Et timer-event", som her: Da er hele evnetnavnet mitt: "Test Et timer-event", og det setter vi inn her: ... og trykker "Done". NB! Når vi nå går tilbake til Device Manager, må vi huske på å vise alle Device Types igjen, fordi den har vi nettopp endret til noe nytt som ikke var valgt før. Så er det bare å stille klokka. Endrer vi tiden på devicen til dette... ... vil eventet også endres: Det gjør ingenting om eventet ditt har andre conditions, de vil ikke bli påvirket av dette. Scriptet har også en rutine for å endre klokkeslettet med eventer, f.eks. hvis man skal stille tilbake flere vekkerklokker etter en ferie. Da kaller man bare rutinen/metoden "Main" (eller lar være å spesifisere rutine), og bruker deviceRef og klokkeslett som parameter. Dette: ... gir dette: ... og selvfølgelig dette:
-
Under "Flows" finnes det en knapp for variabler. Oppretter man variabler der, kan de adresseres som tags i flows. Kjører jeg "example-global-get.js" under "Scripts", hadde jeg forventet å se disse variablene, men de listes ikke. Kan noen kort forklare eller henvise til literatur angående scope på variabler i Homey Scripts? Er objektmodellen den samme under Athom Homey Pro 2019 og 2023?
-
Det er det samme maset hvert år: "Hvorfor må vi alltid ha disse kjedelige juletrelysene? Klart jeg kan bruke RGBW-lys, men de er så... statiske.". Vi har alle vært der. Vel, Twinkly er svaret. Det er juletrelys som kan styres via en app, man kan legge til animasjoner, og man kan til og med lage egne og "tegne" fargene på treet i sanntid. Og nå kan man også selvfølgelig styre treet fra HomeSeer. Lagre scriptet under som Twinkly.vb i /scripts-mappen, endre IPen (nest øverste linje), og lag et event der du kjører "Setup"-funksjonen. Hvis du oppdaterer, så kan du istedenfor kjøre "AddDeviceButtons"-funksjonen og bruke deviceID'en til eksisterende Twinkly-devicer som parameter (en om gangen). Twinkly.vb 'Moskus 2019-2020 Dim IP As String Dim debug As Boolean = False Public Sub Main(ByVal something As Object) End Sub Public Sub ButtonPress(ByVal input As Object) Dim deviceRef As Integer = input(0) IP = DirectCast(hs.GetDeviceByRef(deviceRef), Scheduler.Classes.DeviceClass).Device_Type_String(hs) Dim cmd As String = input(1) If cmd.StartsWith("Brightness_") Then Dim value As Integer = cmd.Split("_")(1) DoCmd("Brightness", value) Else If DoCmd(cmd) Then hs.SetDeviceString(deviceRef, cmd, True) End If If DoCmd(cmd) Then hs.SetDeviceString(deviceRef, cmd.Replace("_", " "), True) End Sub Public Function DoCmd(ByVal command As String, Optional ByVal value As Integer = 100) As Boolean 'SetMode("rt") 'SetMode("demo") 'SetMode("movie") 'SetMode("effect") 'SetMode("off") If debug Then hs.WriteLog("Twinkly", "Starting DoCmd()") Dim code As String = GetRandomCode() If debug Then hs.WriteLog("Twinkly", "Code: " & code) Dim auth As TwinklyAuthentication = Login(code, forceNew:=True) If debug Then hs.WriteLog("Twinkly", "Authentication_token: " & auth.authentication_token) Dim success As Boolean = Verify() If debug Then hs.WriteLog("Twinkly", "Verified: " & success) If command = "Brightness" Then SetBrightness(value) Else SetMode(command) End If Return True End Function Public Sub Setup(ByVal not_used As String) Dim new_ref As Integer = hs.NewDeviceRef("Twinkly") Dim dv As Scheduler.Classes.DeviceClass = hs.GetDeviceByRef(new_ref) dv.Location(hs) = "Twinkly" dv.Location2(hs) = "Twinkly" dv.Can_Dim(hs) = False dv.DeviceType_Set(hs) = New HomeSeerAPI.DeviceTypeInfo dv.Status_Support(hs) = True dv.Can_Dim(hs) = False dv.MISC_Set(hs, HomeSeerAPI.Enums.dvMISC.SHOW_VALUES) 'This is &H100 dv.MISC_Clear(hs, HomeSeerAPI.Enums.dvMISC.STATUS_ONLY) 'This is &H10 hs.SaveEventsDevices() AddDeviceButtons(new_ref) hs.WriteLog("Twinkly", "Initiation done!") End Sub Public Sub AddDeviceButtons(ByVal device_ref As String) Dim devID As Integer = CInt(device_ref) hs.DeviceScriptButton_DeleteAll(devID) hs.DeviceProperty_dvMISC(device_ref, HomeSeerAPI.Enums.eDeviceProperty.MISC_Set, HomeSeerAPI.Enums.dvMISC.SHOW_VALUES) Try hs.WriteLog("Twinkly", "Added button 1: " & hs.DeviceScriptButton_AddButton(devID, "Movie", 101, "Twinkly.vb", "ButtonPress", "Movie", 1, 1, 1)) hs.WriteLog("Twinkly", "Added button 2: " & hs.DeviceScriptButton_AddButton(devID, "Effect", 102, "Twinkly.vb", "ButtonPress", "Effect", 1, 2, 1)) hs.WriteLog("Twinkly", "Added button 3: " & hs.DeviceScriptButton_AddButton(devID, "Demo", 103, "Twinkly.vb", "ButtonPress", "Demo", 1, 3, 1)) hs.WriteLog("Twinkly", "Added button 4: " & hs.DeviceScriptButton_AddButton(devID, "Pause", 104, "Twinkly.vb", "ButtonPress", "RT", 1, 4, 1)) hs.WriteLog("Twinkly", "Added button 5: " & hs.DeviceScriptButton_AddButton(devID, "Off", 0, "Twinkly.vb", "ButtonPress", "Off", 1, 5, 1)) For i As Integer = 10 To 100 Step 10 hs.WriteLog("Twinkly", "Added dimming " & i & " : " & hs.DeviceScriptButton_AddButton(devID, (i & "%").ToString, i, "Twinkly.vb", "ButtonPress", "Brightness_" & i, 2 + Math.Floor(i / 51), (i / 10 - Math.Floor(i / 51) * 5), 1)) Next Catch ex As Exception hs.WriteLog("Twinkly", "Error adding buttons: " & ex.Message) End Try End Sub Public Sub SetMovieConfig(ByVal frameDelay As Integer, ByVal numberOfLEDs As Integer, ByVal framesNumber As Integer, ByVal loopType As Integer) Dim data As New System.Collections.Generic.Dictionary(Of String, Integer) data.Add("frame_delay", frameDelay) data.Add("leds_number", numberOfLEDs) data.Add("frames_number", framesNumber) Dim output As String = RunAPI("led/movie/config", Newtonsoft.Json.JsonConvert.SerializeObject(data)) If debug Then hs.WriteLog("Twinkly", "SetMovieConfig: " & output) End Sub Public Sub GetMovieConfig() ' {"frame_delay":66,"leds_number":175,"loop_type":0,"frames_number":212,"sync":{"mode":"none","slave_id":"","master_id":""},"code":1000} Dim output As String = RunAPI("led/movie/config") If debug Then hs.WriteLog("Twinkly", "GetMovieConfig: " & output) End Sub Public Sub GetMovieFull() If debug Then hs.WriteLog("Twinkly", "GetMovieFull: ") Dim output As Byte() = RunAPIraw("led/movie/all") If debug Then hs.WriteLog("Twinkly", ConvertByteArrayToString(output) & " ... done!") End Sub Public Sub SetMovieFull(ByVal octetString As String) Dim movie() As Byte = ConvertStringToByteArray(octetString) If debug Then hs.WriteLog("Twinkly", "SetMovieFull: ") Dim ret = RunAPIraw("led/movie/full", movie) If debug Then hs.WriteLog("Twinkly", System.Text.Encoding.ASCII.GetString(ret) & " ... done!") End Sub ''' <summary> ''' Get brightness ''' </summary> Public Function GetBrightness() As Integer Console.Write("Getting brigthness...") Dim output As String = RunAPI("led/out/brightness") Dim json = Newtonsoft.Json.JsonConvert.DeserializeObject(Of Object)(output) Return json("value") End Function ''' <summary> ''' Set brightness ''' </summary> ''' <param name="brightness">0-100</param> Public Sub SetBrightness(ByVal brightness As Integer) If debug Then hs.WriteLog("Twinkly", "Setting brigthness to '" & brightness & "'...") Dim data As New System.Collections.Generic.Dictionary(Of String, Object) data.Add("mode", "enabled") data.Add("value", brightness) data.Add("type", "A") Dim output As String = RunAPI("led/out/brightness", Newtonsoft.Json.JsonConvert.SerializeObject(data)) If debug Then hs.WriteLog("Twinkly", IIf(output.Contains("1000"), " was a success!", " failed. :(")) End Sub ''' <summary> ''' Sets the display ''' </summary> ''' <param name="mode">rt, movie, demo, restart, effect, off</param> Public Sub SetMode(ByVal mode As String) If debug Then hs.WriteLog("Twinkly", "Setting mode to '" & mode & "'") Dim data As New System.Collections.Generic.Dictionary(Of String, String) data.Add("mode", mode.ToLower()) Dim output As String = RunAPI("led/mode", Newtonsoft.Json.JsonConvert.SerializeObject(data)) Dim success As Boolean = output.Contains("1000") If debug Then hs.WriteLog("Twinkly", "Mode set: " & IIf(success, " was a success!", " failed. :(")) If Not success And debug Then hs.WriteLog("Twinkly", "Output: " & output) End Sub Public Function GetAuthentication() As TwinklyAuthentication Dim auth As TwinklyAuthentication = New TwinklyAuthentication Dim authString As String = hs.GetINISetting("Twinkly", "Authentication", "", "Twinkly.ini") Try If authString <> "" Then auth = Newtonsoft.Json.JsonConvert.DeserializeObject(Of TwinklyAuthentication)(authString) End If Catch ex As Exception End Try Return auth End Function Public Function Verify() As Boolean Dim auth As TwinklyAuthentication = GetAuthentication() Dim data As New System.Collections.Generic.Dictionary(Of String, String) data.Add("challenge-response", auth.challengeresponse) Dim output As String = RunAPI("verify", Newtonsoft.Json.JsonConvert.SerializeObject(data)) Return output.Contains("1000") End Function Public Function Login(ByVal challenge As String, Optional ByVal forceNew As Boolean = False) As TwinklyAuthentication Dim auth As TwinklyAuthentication = Nothing Dim authString As String = "" authString = hs.GetINISetting("Twinkly", "Authentication", "", "Twinkly.ini") Try If authString <> "" Then auth = Newtonsoft.Json.JsonConvert.DeserializeObject(Of TwinklyAuthentication)(authString) Catch ex As Exception End Try If auth Is Nothing OrElse forceNew Then Dim data As New System.Collections.Generic.Dictionary(Of String, String) data.Add("challenge", challenge) Dim output As String = RunAPI("login", Newtonsoft.Json.JsonConvert.SerializeObject(data)) hs.SaveINISetting("Twinkly", "Authentication", output, "Twinkly.ini") auth = Newtonsoft.Json.JsonConvert.DeserializeObject(Of TwinklyAuthentication)(output) End If Return auth End Function Private Function RunAPI(ByVal urlFunction As String, Optional ByVal query As String = "") As String Dim source As String = "" Dim url As String = "http://" & IP & "/xled/v1/" & urlFunction Dim auth As TwinklyAuthentication = GetAuthentication() Using client As New System.Net.WebClient client.Headers.Add("Content-Type", "application/json") If auth.authentication_token <> "" Then client.Headers.Add("X-Auth-Token", auth.authentication_token) End If If query <> "" Then source = client.UploadString(url, "POST", query) Else source = client.DownloadString(url) End If End Using Return source End Function Private Function RunAPIraw(ByVal urlFunction As String, Optional ByVal bytes() As Byte = Nothing) As Byte() Dim auth As TwinklyAuthentication = GetAuthentication() Dim source As Byte() = {} Dim url As String = "http://" & IP & "/xled/v1/" & urlFunction Using client As New System.Net.WebClient Net.ServicePointManager.DefaultConnectionLimit = 9999 client.Headers.Add("Content-Type", "application/octet-stream") If auth.authentication_token <> "" Then client.Headers.Add("X-Auth-Token", auth.authentication_token) End If If bytes IsNot Nothing Then source = client.UploadData(New Uri(url), bytes) Else source = client.DownloadData(url) End If End Using Return source End Function Public Function GetRandomCode(Optional ByVal forceNew As Boolean = False) As String Dim code As String = hs.GetINISetting("Twinkly", "Code", "", "Twinkly.ini") If code = "" OrElse forceNew Then code = GetRandomString(32) hs.SaveINISetting("Twinkly", "Code", code, "Twinkly.ini") End If Return code End Function Private Function GetRandomString(ByVal length As Integer) Dim s As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" Dim r As New Random Dim sb As New Text.StringBuilder For i As Integer = 0 To length - 1 Dim idx As Integer = r.Next(0, 35) sb.Append(s.Substring(idx, 1)) Next Return sb.ToString() End Function Public Function ConvertStringToByteArray(ByVal input As String) As Byte() Dim lst As New System.Collections.Generic.List(Of Byte) For i As Integer = 0 To input.Length - 1 Step 2 Dim temp As String = input.Substring(i, 2) Dim val As Integer = Convert.ToInt32(temp, 16) lst.Add(Convert.ToByte(val)) Next Return lst.ToArray() End Function Public Function ConvertByteArrayToString(ByVal bytes() As Byte) As String Dim ret As String = "" For Each b As Byte In bytes ret &= Convert.ToChar(b).ToString() Next Return ret End Function Public Class TwinklyAuthentication Private _authentication_token As String Public Property authentication_token() As String Get Return _authentication_token End Get Set(ByVal value As String) _authentication_token = value End Set End Property Private _authentication_token_expires_in As Integer Public Property authentication_token_expires_in() As Integer Get Return _authentication_token_expires_in End Get Set(ByVal value As Integer) _authentication_token_expires_in = value End Set End Property Private _challengeresponse As String Public Property challengeresponse() As String Get Return _challengeresponse End Get Set(ByVal value As String) _challengeresponse = value End Set End Property Private _code As Integer Public Property code() As Integer Get Return _code End Get Set(ByVal value As Integer) _code = value End Set End Property End Class Gammelt script: Da får du en device som dette: Gå inn på Devicen, og gå til Advanced. Legg så IP-adressen til Twinkly-lenken inn under "Device Type (String)": ... og siden vi endrer Device Types, må vi huske å vise alle etter på: Den nye versjonen støtter altså flere lenker på samme script, man slipper å lage kopier av scriptet hvis man har flere lenker.
-
Tips fra @Andreas gjorde at jeg oppdaterte et gammelt (og ubrukelig) script slik at det nå er "brukelig" igjen. ResponsiveVoice.vb Sub Main(Byval input as Object) Dim speakThis as String = hs.ReplaceVariables(input.ToString) Dim remoteFile as String = "https://code.responsivevoice.org/getvoice.php?t=" & speakThis & "&tl=no&sv=g2&vn=&pitch=0.5&rate=0.5&vol=1" Dim localFile as String = hs.GetAppPath & "\tts.mp3" My.Computer.Network.DownloadFile(remoteFile, localFile, "", "", False, 3000, True) End Sub ... lagrer en MP3-fil som heter "tts.mp3" i HS3-katalogen din. Denne kan du spille av via Squeezebox, Sonos, eller HS3 Speaker client. "Paremeters" er selve strengen. Du kan bruke Replacement Variables. "Wait for script to finish before continuing" er viktig for å laste ned filen før du spiller den av. Jeg testet dette over kl. 11:15 og spilte av "Dette er en test! Klokken er kvart over elleve!". Imponerende.
-
Å vite om det er helg eller ikke er ganske praktisk for hjemmeautomasjon. De aller fleste har andre rutiner i helgene enn de har i ukedagene. Hos oss er derimot rutinene for fridager omtrent prikk lik dager i helgen, så det hadde jo vært praktisk om man istedenfor å sjekke om det er helg, kunne sjekke om det er en fridag. Og nå kan vi det. Basert på @xibriz sitt glimrende PHP-script for å sjekke for offentlige høytider (og omskrevet til VB.NET) har jeg lagt til en rutine ekstra, som bl.a. sjekke om det faktisk er helg eller om det er noen andre unntak lagt inn. Du trenger en virtuell device med "Control Use" for Off og On definert (under Status Grapics -> Status-kolonne). Her er min: Device Ref til denne brukes som parameter i scriptet. Scriptet trigges ved midnatt hver dag for å sjekke om dagen i dager en fridag eller ei. Fridager.vb Sub Main(ByVal deviceReference As String) 'Moskus 2017 Dim devRef As Integer = Integer.Parse(deviceReference.ToString) Dim isCurrentDateHoliday As Boolean = False If Not isCurrentDateHoliday Then isCurrentDateHoliday = IsOfficialHoliday(Now) 'Sjekker offisielle helligdager If Not isCurrentDateHoliday Then isCurrentDateHoliday = IsCustomHoliday(Now) 'Sjekker egen-spesifiserte dager If isCurrentDateHoliday Then hs.CAPIControlHandler(hs.CAPIGetSingleControlByUse(devRef, HomeSeerAPI.ePairControlUse._On)) Else hs.CAPIControlHandler(hs.CAPIGetSingleControlByUse(devRef, HomeSeerAPI.ePairControlUse._Off)) End If End Sub Public Function IsCustomHoliday(ByVal _date As Date) As Boolean _date = _date.Date 'In case time was added 'For eksempel sjekkeom det er en lørdag eller søndag If _date.DayOfWeek = DayOfWeek.Saturday Then Return True If _date.DayOfWeek = DayOfWeek.Sunday Then Return True 'Jeg har alltid fri i romjulen If _date.Month = 12 Then If _date.Day >= 27 AndAlso _date.Day <= 31 Then Return True End If End If 'Andre spesifikke dager kan legges i listen, f.eks. har barnehagen planleggingsdager Dim dateList As New System.Collections.Generic.List(Of Date) dateList.Add(New Date(2017, 4, 18)) If dateList.Contains(_date) Then Return True 'Har vi kommet så langt er det ingen fridager, returner "False" Return False End Function Public Function IsOfficialHoliday(ByVal _date As Date) As Boolean 'translated php script form xibriz: https://www.diskusjon.no/index.php?showtopic=1084239 _date = _date.Date 'in case time was added Dim easterDate As Date = GetEasterDate(_date.Year) 'Sjekker om datoen er 1. Januar If _date = New Date(_date.Year, 1, 1) Then Return True 'Sjekker om datoen er pamlesøndag (1. påskedag - 7 dager) If _date = easterDate.AddDays(-7) Then Return True 'Sjekker om datoen er skjærtorsdag (1. påskedag - 3 dager) If _date = easterDate.AddDays(-3) Then Return True 'Sjekker om datoen er langfredag (1. påskedag - 2 dager) If _date = easterDate.AddDays(-2) Then Return True 'Sjekker om datoen er 1. påskedag If _date = easterDate Then Return True 'Sjekker om datoen er 2. påskedag (1. påskedag + 1 dag) If _date = easterDate.AddDays(1) Then Return True 'Sjekker om datoen er 1. mai (offentlig høytidsdag) If _date = New Date(_date.Year, 5, 1) Then Return True 'Sjekker om datoen er 17. mai (grunnlovsdag) If _date = New Date(_date.Year, 5, 17) Then Return True 'Sjekker om datoen er kristi himmelfartsdag (40. påskedag) If _date = easterDate.AddDays(39) Then Return True 'Sjekker om datoen er 1. pinsedag (50. påskedag) If _date = easterDate.AddDays(49) Then Return True 'Sjekker om datoen er 2 pinsedag (51. påskedag) If _date = easterDate.AddDays(50) Then Return True 'Sjekker om datoen er 1. juledag (25. desember) If _date = New Date(_date.Year, 12, 25) Then Return True 'Sjekker om datoen er 2 juledag (26. desember) If _date = New Date(_date.Year, 12, 26) Then Return True Return False End Function Public Function GetEasterDate(ByVal Year As Integer) As Date 'Originally taken from: http://www.thoughtproject.com/Snippets/Easter/Easter.vb.txt Dim a As Integer Dim b As Integer Dim c As Integer Dim d As Integer Dim e As Integer Dim f As Integer Dim g As Integer Dim h As Integer Dim i As Integer Dim k As Integer Dim l As Integer Dim m As Integer Dim n As Integer Dim p As Integer If Year < 1583 Then Return Nothing Else ' Step 1: Divide the year by 19 and store the ' remainder in variable A. Example: If the year ' is 2000, then A is initialized to 5. a = Year Mod 19 ' Step 2: Divide the year by 100. Store the integer ' result in B and the remainder in C. b = Year \ 100 c = Year Mod 100 ' Step 3: Divide B (calculated above). Store the ' integer result in D and the remainder in E. d = b \ 4 e = b Mod 4 ' Step 4: Divide (b+8)/25 and store the integer ' portion of the result in F. f = (b + 8) \ 25 ' Step 5: Divide (b-f+1)/3 and store the integer ' portion of the result in G. g = (b - f + 1) \ 3 ' Step 6: Divide (19a+b-d-g+15)/30 and store the ' remainder of the result in H. h = (19 * a + b - d - g + 15) Mod 30 ' Step 7: Divide C by 4. Store the integer result ' in I and the remainder in K. i = c \ 4 k = c Mod 4 ' Step 8: Divide (32+2e+2i-h-k) by 7. Store the ' remainder of the result in L. l = (32 + 2 * e + 2 * i - h - k) Mod 7 ' Step 9: Divide (a + 11h + 22l) by 451 and ' store the integer portion of the result in M. m = (a + 11 * h + 22 * l) \ 451 ' Step 10: Divide (h + l - 7m + 114) by 31. Store ' the integer portion of the result in N and the ' remainder in P. n = (h + l - 7 * m + 114) \ 31 p = (h + l - 7 * m + 114) Mod 31 ' At this point p+1 is the day on which Easter falls. ' n is 3 for March or 4 for April. Return DateSerial(Year, n, p + 1) End If End Function Merk: Det kan være du vil fjerne noen linjer i scriptet eller i det minste kommentere dem ut. Det er f.eks. ikke sikkert at du har fri uka etter påske: dateList.Add(New Date(2017, 4, 18)) ... og hvis ikke, kan du fjerne denne linjen. Det er heller ikke sikkert du har fri romjulen, så da bør du fjerne dette: If _date.Month = 12 Then If _date.Day >= 27 AndAlso _date.Day <= 31 Then Return True End If End If Du kan også selvfølgelig legge til dine egne unntak for arbeidsdager hvis du ønsker det. Har du fri hver fredag, så kan du jo bare legge det til. Jeg har nå byttet ut alle sjekker på om det er helg eller ikke til å sjekke om "Fridag" er på eller ikke. Når jeg tenker meg om tror jeg at jeg skal sette "On" til å være "Fridag" og "Off" til å være "Arbeidsdag". Som sagt; så gjort: ... som da blir slik: EDIT: 17. mai var satt til å være 17.01 istedenfor 17.05. Korrigert. Versjon med to devicer, en for dagen i dag og en for dagen i morgen:
-
Jeg har en del virtuelle enheter som jeg ønsker å kunne "nullstille" ved å sette verdien på alle enhetene til 0. Har forsøkt å bruke hs.SetDeviceValueByRef men får det ikke helt til å fungere. Hvordan kan jeg enklest mulig liste opp alle adressene som jeg ønsker å sette til 0? PS. Ikke veldig bevandret med script, men dette er sikkert en smal sak for dere som kan scripting, så setter stor pris på om noen ville ta seg tid til å gi meg en "ferdig" script-tekst jeg kan kopiere.
-
To scripts som logger verdier til flate tekstfiler, med tidspunktet og verdien eller statusen separert med tab. Kan da enkelt limes inn i f.eks. Excel. LogValueToFile.vb Sub Main(parm As Object) Dim deviceRef As Integer = parm.ToString() Dim out As String = Now.ToShortDateString & " " & Now.ToLongTimeString & vbTab & hs.DeviceValueEx(deviceRef).ToString("f1") Try My.Computer.FileSystem.WriteAllText(hs.GetAppPath & "\Logs\" & deviceRef & ".txt", out & vbNewLine, True) Catch ex As Exception hs.WriteLog("LogValueToFile ERROR", ex.Message) End Try End Sub Å hente status kan være verre, for det er flere måter å gjøre det på. LogStatusToFile.vb Sub Main(parm As Object) Dim deviceRef As Integer = parm.ToString() Dim out As String = Now.ToShortDateString & " " & Now.ToLongTimeString & vbTab & GetDeviceString(deviceRef) Try My.Computer.FileSystem.WriteAllText(hs.GetAppPath & "\Logs\" & deviceRef & ".txt", out & vbNewLine, True) Catch ex As Exception hs.WriteLog("LogStatusToFile ERROR", ex.Message) End Try End Sub Function GetDeviceString(ByVal DeviceRef As Integer) As String 'Henter device string fra HS Dim devstring As String = hs.DeviceString(DeviceRef) If devstring <> String.Empty Then Return devstring 'Henter devicestring directe fra CAPI-status, hvis den finnes devstring = hs.CAPIGetStatus(DeviceRef).Status If devstring <> String.Empty Then Return devstring 'Henter devicestring fra CAPI beskrivelse (basert på value) devstring = GetCapiString(DeviceRef) If devstring <> String.Empty Then Return devstring 'Henter devicestring fra device class Dim dev As Scheduler.Classes.DeviceClass = hs.GetDeviceByRef(DeviceRef) devstring = dev.devString(Nothing) If devstring <> String.Empty Then Return devstring Return "String not found for " & DeviceRef & ", value = " & hs.DeviceValueEx(DeviceRef) End Function Function GetCapiString(ByVal DeviceRef As Integer) As String For Each CAPI As HomeSeerAPI.CAPIControl In hs.CAPIGetControl(DeviceRef) If CAPI.ControlValue = hs.DeviceValue(DeviceRef) Then Return CAPI.Label.ToString Next Return String.Empty End Function Kalles med device Ref som parameter.
-
Hei! Utvikleren til Device History plugin-et har vore meget serviceinnstilt og levert kode for å hente ut gjennomsnittsverdi frå sist time og skrive verdien til et virtuellt device. På denne måten kan eg sammenligne direkte med en verdi, istedenfor å gjennomsnittsberegne for kvar enkelt funksjon. Koden er som følger: Public Sub UpdateHourlyStats(parms As String) Dim intSourceRef As Integer Dim intDestRef As Integer Dim dtmFrom As Date Dim dtmTo As Date Dim strDeviceStats As String Dim astrStats() As String Const IDX_STATS_MIN As Integer = 0 Const IDX_STATS_MAX As Integer = 1 Const IDX_STATS_AVG As Integer = 2 Const IDX_STATS_COUNT As Integer = 3 Dim dblMin As Double Dim dblMax As Double Dim dblAvg As Double Dim intCount As Integer 'figure out the parameters intSourceRef = CType(parms.Split(";")(0), Integer) intDestRef = CType(parms.Split(";")(1), Integer) dtmTo = Date.Now dtmFrom = dtmTo.AddHours(-1) hs.WriteLog("Device History", "Getting updated stats for device " & intSourceRef & " from '" & dtmFrom.ToString() & "' to '" & dtmTo.ToString() & "' ...") 'Ask the plugin for the stats strDeviceStats = hs.PluginFunction("Device History", "", "GetRangeStats", {intSourceRef.ToString(), dtmFrom.ToString(), dtmTo.ToString()}) 'Parse the response into discrete variables astrStats = strDeviceStats.Split("|") If astrStats.Length() = 4 Then dblMin = astrStats(IDX_STATS_MIN) dblMax = astrStats(IDX_STATS_MAX) dblAvg = astrStats(IDX_STATS_AVG) intCount = astrStats(IDX_STATS_COUNT) 'Do something with the output hs.WriteLog("Device History", "Device " & intSourceRef & " ranged from " & dblMin & " to " & dblMax & ", with an average value of " & dblAvg & " taken from " & intCount & " changes.") hs.WriteLog("Device History", "Updating device " & intDestRef & " with value " & dblAvg) hs.SetDeviceValueByRef(intDestRef, dblAvg, True) Else hs.WriteLog("Error", "Retrieval of stats for device " & intSourceRef & " failed.") End If End Sub Korleis lagre som .vb fil? Og så må eg ha litt rettleiing på kva som er rett device-ref. Er det root-device, eller ref på funksjoner etc. Edit: I tillegg ser det ut til eg også må lære å legge inn kode som skjult tekst og rett formatering, slik som de andre bruker.
-
Det hender jeg eksperimenterer med Z-wave, til og med på hovedsystemet. Jeg har et par Z-wave-interfacer jeg bytter mellom (kjører restore av backup til et nytt interface før for mye testing), og det fjerner all potensiell routing-informasjon. I løpet av de første timene prøver altså huset å "finne seg selv", alt går litt tregt, og det blir høyere risiko for at noe er satt til "Unknown". Jeg skrev et script for å finne disse enhetene, og så polle dem for å faktisk lese statusen de har. Det hjelper både for å få fjernet de irriterende "Unknown"-status'ene, og det hjelper på å bedre routingen fordi kommandoen blir utført. For at dette skal fungere ut av esken må HomeSeer finne seg selv på localholst på port 80. Hvis ikke må du endre "Dim url as String"-linja. CheckForUnknown.vb Public Sub Main(ByVal params As Object) 'Moskus 2020 Dim subStart As DateTime = DateTime.UtcNow Dim url As String = "http://localhost/json?request=getstatus" Dim json As String = "" Dim DEBUG As Boolean = False If DEBUG Then hs.WriteLog("CheckForErrors", "Downloading data... ") Using client As New System.Net.WebClient json = client.DownloadString(url) json = json.ToLower() End Using If DEBUG Then hs.WriteLog("CheckForErrors", "Download done!") Dim searchString As String = ("{""ref"":").ToLower() Dim errorSearchString As String = ("""status"":""Unknown"",""device_type_string"":""Z-Wave Switch").ToLower() Dim lst As New System.Collections.Generic.List(Of Integer) Dim start As Integer = 0 If json.IndexOf(errorSearchString) > 0 Then ' Yes, we have errors, lets find the devices by looping through all devices While start <> -1 Dim deviceJsonStart As Integer = json.IndexOf(searchString, start) If deviceJsonStart = -1 Then Exit While Dim deviceJsonEnd As Integer = json.IndexOf(searchString, deviceJsonStart + searchString.Length) If deviceJsonEnd = -1 Then Exit While Dim deviceJson As String = json.Substring(deviceJsonStart, deviceJsonEnd - deviceJsonStart) 'This is the JSON for a device If deviceJson.Contains(errorSearchString) Then 'Check if the device contains the error and get the deviceRef if it doesn't Dim deviceRef As Integer = deviceJson.Substring(searchString.Length, deviceJson.IndexOf(",") - searchString.Length) lst.Add(deviceRef) If DEBUG Then hs.WriteLog("CheckForErrors", "Found reference '" + deviceRef.ToString + "'") End If start = json.IndexOf(searchString, deviceJsonStart + 10) End While End If For Each d As Integer In lst Dim dev As Scheduler.Classes.DeviceClass = hs.GetDeviceByRef(d) Dim devName As String = dev.Location2(hs) & ", " & dev.Location(hs) & ", " & dev.Name(hs) Dim pollResult As HomeSeerAPI.IPlugInAPI.PollResultInfo = hs.PluginFunction("Z-Wave", "", "PollDevice", New Object() {d}) hs.WriteLog("CheckForErrors", "Poll of device " & d.ToString & " (" & devName & ") returned " & pollResult.Result.ToString & " (" & pollResult.Value & ")") 'Check if the device has the correct value If pollResult.Result = HomeSeerAPI.IPlugInAPI.enumPollResult.OK OrElse pollResult.Result = HomeSeerAPI.IPlugInAPI.enumPollResult.Timeout_OK Then Dim pollValue As Integer = pollResult.Value Dim devValue As Integer = hs.DeviceValue(d) 'Set the device to the correct value If devValue <> pollValue Then For Each CAPI As HomeSeerAPI.CAPIControl In hs.CAPIGetControl(d) If CAPI.ControlValue = devValue Then Dim response As CAPIControlResponse = hs.CAPIControlHandler(CAPI) hs.WriteLog("CheckForErrors", "Set " & d.ToString & " (" & devName & ") to " & CAPI.Label & ": " & response.ToString) Exit For End If Next End If End If Next hs.WriteLog("CheckForErrors", "Done! Elapsed time: " & Math.Round(DateTime.UtcNow.Subtract(subStart).TotalSeconds, 2) & " seconds") End Sub Jeg kjører dette scriptet i et event hver 10. minutt. Men jeg har også en begrensning på at det ikke må ha vært bevegelse i huset i løpet av 5 minutter for å redusere trafikken når routingen er på det verste. Jeg hadde selvfølgelig tenkt å disable scriptet når det ikke var behov for det, men ellers merker jeg ikke noe til det for det er særdeles sjeldent scriptet finner "Unknown" lenger, det ser jeg jo nå i loggen.
-
Hei. Jeg har laget et script for å starte og parkere Gardena Smart Sileno gressklippere. Testet og fungerer på min Gardena Smart Sileno R100Li. Legg inn e-postadressen, passordet, og navnet på klipperen på linje 12->14 i skriptet. Sett logJson = True for å se alt i json-responsen fra Gardena. Det ligger mye nyttig informasjon i responsen fra get_device_id. Kall scriptet med parameter start eller stop. Disse parametrene blir så brukt lenger nede i scriptet til: 'Available start commands: 'Start according to schedule: "{""name"":""start_resume_schedule"", ""parameters"":{}}" 'Start overriding schedule. Run for 1440 minutes: "{""name"":""start_override_timer"", ""parameters"":{""duration"": 1440}}" 'Available stop commands: 'Park and pause all schedules: "{""name"":""park_until_further_notice""}" 'Park and start again at next schedule: "{""name"":""park_until_next_timer""}" Imports System.IO Imports System.Net '*** Choose if json-responces should get written to the log *** Const logJson As Boolean = False '************************************************************** Public Sub Main(ByVal command As String) '*** Put in e-mailadress and password and lawnmover-name *** '*** They must be exactly as entered into the Gardena app *** Dim email As String = "[email protected]" Dim password As String = "Mypassword" Dim mower_name As String = "Name_of_lawnmower_in_gardena_app" '************************************************* '*** NO NEED TO EDIT BEHIND THIS POINT! *** '************************************************* 'Get token and username Dim jsonGetToken As String = "{""sessions"":{""email"":""" & email & """,""password"":""" & password & """}}" Dim tokenAndUser() As String = getToken(jsonGetToken) 'Get location Dim location As String = getLocation(tokenAndUser) 'Get device-id for lawnmover set in mower_name Dim locationAndToken(3) as String locationAndToken(0) = tokenAndUser(0) locationAndToken(1) = location locationAndToken(2) = mower_name Dim deviceId As String = getdeviceId(locationAndToken) 'Send start or stop command to mower Dim data(4) as String data(0) = tokenAndUser(0) data(1) = location data(2) = deviceId data(3) = command sendCommand(data) End Sub Public Function getToken(json As string) As String() 'Get token and user ID based on e-mail and password Dim strURL As String = "https://sg-api.dss.husqvarnagroup.net/sg-1/sessions" Dim myWebReq As HttpWebRequest Dim myWebResp As HttpWebResponse Dim encoding As New System.Text.UTF8Encoding Dim sr As StreamReader Dim result(2) As String Try Dim data As Byte() = encoding.GetBytes(json) myWebReq = DirectCast(WebRequest.Create(strURL), HttpWebRequest) myWebReq.ContentType = "application/json" myWebReq.ContentLength = data.Length myWebReq.Method = "POST" Dim myStream As Stream = myWebReq.GetRequestStream() If data.Length > 0 Then myStream.Write(data, 0, data.Length) myStream.Close() End If myWebResp = DirectCast(myWebReq.GetResponse(), HttpWebResponse) sr = New StreamReader(myWebResp.GetResponseStream()) Dim responseText As String = sr.ReadToEnd() if logJson Then hs.WriteLog("Gardena", "Response getToken: " & responseText) End If 'Search json for token Dim sSource As String = responseText 'String that is being searched Dim sDelimStart As String = """token"":""" 'First delimiting word Dim sDelimEnd As String = """,""user_id" 'Second delimiting word Dim nIndexStart As Integer = sSource.IndexOf(sDelimStart) 'Find the first occurrence of f1 Dim nIndexEnd As Integer = sSource.IndexOf(sDelimEnd) 'Find the first occurrence of f2 If nIndexStart > -1 AndAlso nIndexEnd > -1 Then '-1 means the word was not found. Dim token As String = Strings.Mid(sSource, nIndexStart + sDelimStart.Length + 1, nIndexEnd - nIndexStart - sDelimStart.Length) 'Crop the text between hs.WriteLog("Gardena", "Token: " & token) 'We got the token, continue to get the user id sDelimStart = "user_id"":""" 'First delimiting word sDelimEnd = """,""refresh_token" 'Second delimiting word nIndexStart = sSource.IndexOf(sDelimStart) 'Find the first occurrence of f1 nIndexEnd = sSource.IndexOf(sDelimEnd) 'Find the first occurrence of f2 If nIndexStart > -1 AndAlso nIndexEnd > -1 Then '-1 means the word was not found. Dim user As String = Strings.Mid(sSource, nIndexStart + sDelimStart.Length + 1, nIndexEnd - nIndexStart - sDelimStart.Length) 'Crop the text between hs.WriteLog("Gardena", "User: " & user) result(0) = token result(1) = user return result Else hs.WriteLog("Gardena", "Error: Did not receive user ID") End If Else hs.WriteLog("Gardena", "Error: Did not receive token") End If Catch ex As Exception : hs.writelog("Gardena", "Error: " & ex.Message.ToString) End Try End Function Public Function getLocation(tokenAndUser() As String) As String 'Get location based on token and user id Dim token As String = tokenAndUser(0) Dim user As String = tokenAndUser(1) Dim strURL As String = "https://sg-api.dss.husqvarnagroup.net/sg-1/locations/?user_id=" & user Dim myWebReq As HttpWebRequest Dim myWebResp As HttpWebResponse Dim sr As StreamReader Try myWebReq = DirectCast(WebRequest.Create(strURL), HttpWebRequest) myWebReq.ContentType = "application/json" myWebReq.Method = "GET" myWebReq.Headers.Add("X-session", token) myWebResp = DirectCast(myWebReq.GetResponse(), HttpWebResponse) sr = New StreamReader(myWebResp.GetResponseStream()) Dim responseText As String = sr.ReadToEnd() if logJson Then hs.WriteLog("Gardena", "Response getLocation: " & responseText) End if 'Search json for location Dim sSource As String = responseText 'String that is being searched Dim sDelimStart As String = """id"":""" 'First delimiting word Dim sDelimEnd As String = """,""name" 'Second delimiting word Dim nIndexStart As Integer = sSource.IndexOf(sDelimStart) 'Find the first occurrence of f1 Dim nIndexEnd As Integer = sSource.IndexOf(sDelimEnd) 'Find the first occurrence of f2 If nIndexStart > -1 AndAlso nIndexEnd > -1 Then '-1 means the word was not found. Dim location As String = Strings.Mid(sSource, nIndexStart + sDelimStart.Length + 1, nIndexEnd - nIndexStart - sDelimStart.Length) 'Crop the text between hs.WriteLog("Gardena", "Location: " & location) return location Else hs.WriteLog("Gardena", "Error: Did not receive location") End If Catch ex As Exception : hs.writelog("Gardena", "Error: " & ex.Message.ToString) End Try End Function Public Function getdeviceId(tokenAndLocation() As String) As String 'Get device id for lawnmover based on location and mower_name Dim token As String = tokenAndLocation(0) Dim location As String = tokenAndLocation(1) Dim mower_name As String = tokenAndLocation(2) Dim strURL As String = "https://sg-api.dss.husqvarnagroup.net/sg-1/devices?locationId=" & location Dim myWebReq As HttpWebRequest Dim myWebResp As HttpWebResponse Dim sr As StreamReader Try myWebReq = DirectCast(WebRequest.Create(strURL), HttpWebRequest) myWebReq.ContentType = "application/json" myWebReq.Method = "GET" myWebReq.Headers.Add("X-session", token) myWebResp = DirectCast(myWebReq.GetResponse(), HttpWebResponse) sr = New StreamReader(myWebResp.GetResponseStream()) Dim responseText As String = sr.ReadToEnd() if logJson Then hs.WriteLog("Gardena", "Response getLocation: " & responseText) End If 'Finn Device ID Dim sSource As String = responseText 'String that is being searched Dim sDelimEnd As String = """,""name"":""" & mower_name & """,""category"":""mower""" 'Second delimiting word Dim nIndexStart As Integer = sSource.IndexOf(sDelimEnd) - 36 Dim nIndexEnd As Integer = sSource.IndexOf(sDelimEnd) 'Find the first occurrence of f2 If nIndexStart > -1 AndAlso nIndexEnd > -1 Then '-1 means the word was not found. Dim deviceId As String = Strings.Mid(sSource, nIndexStart + 1, nIndexEnd - nIndexStart) 'Crop the text between hs.WriteLog("Gardena", "Device ID: " & deviceId) return deviceId Else hs.WriteLog("Gardena", "Error: Did not receive device ID") End If Catch ex As Exception : hs.writelog("Gardena", "Error: " & ex.Message.ToString) End Try End Function Public Function sendCommand(data() As String) 'Send start or stop to the mower. Dim token As String = data(0) Dim location As String = data(1) Dim device As String = data(2) Dim command As String = data(3) Dim json As String '*** Here you can change what start and stop does.*** 'Available start commands: 'Start according to schedule: "{""name"":""start_resume_schedule"", ""parameters"":{}}" 'Start overriding schedule. Run for 1440 minutes: "{""name"":""start_override_timer"", ""parameters"":{""duration"": 1440}}" 'Available stop commands: 'Park and pause all schedules: "{""name"":""park_until_further_notice""}" 'Park and start again at next schedule: "{""name"":""park_until_next_timer""}" if command = "start" Then json = "{""name"":""start_resume_schedule"", ""parameters"":{}}" else if command = "stop" Then json = "{""name"":""park_until_further_notice""}" else hs.writelog("Gardena", "Error: Angi start eller stop som parameter") End If Dim strURL As String = "https://sg-api.dss.husqvarnagroup.net/sg-1/devices/" & device & "/abilities/mower/command?locationId=" & location Dim myWebReq As HttpWebRequest Dim myWebResp As HttpWebResponse Dim encoding As New System.Text.UTF8Encoding Dim sr As StreamReader Try Dim data As Byte() = encoding.GetBytes(json) myWebReq = DirectCast(WebRequest.Create(strURL), HttpWebRequest) myWebReq.ContentType = "application/json" myWebReq.ContentLength = data.Length myWebReq.Headers.Add("X-session", token) myWebReq.Method = "POST" Dim myStream As Stream = myWebReq.GetRequestStream() If data.Length > 0 Then myStream.Write(data, 0, data.Length) myStream.Close() End If myWebResp = DirectCast(myWebReq.GetResponse(), HttpWebResponse) sr = New StreamReader(myWebResp.GetResponseStream()) Dim responseText As String = sr.ReadToEnd() hs.WriteLog("Gardena", "Sent command: " & command) Catch ex As Exception : hs.writelog("Gardena", "Error: " & ex.Message.ToString) End Try End Function
-
Sub Main(ByVal input As Object) Dim deviceRef As Integer = input.ToString Dim weekNumber As Integer = DatePart(DateInterval.WeekOfYear, Date.Now, FirstDayOfWeek.Monday, FirstWeekOfYear.System) hs.SetDeviceValueByRef(input, weekNumber, True) hs.SetDeviceString(input, "Uke " & weekNumber, False) End Sub
-
- 1
-
Jeg mener dette er min første post her - jeg har hatt mye hjelp av å lese her, og nå er det kanskje på tide jeg bidrar litt. Jeg har kikket etter et script som gjør det jeg ønsker (...og ikke minst på den måten jeg ønsker:-) uten å finne det - og har derfor prøvd å skrive et selv. Jeg har "hentet inspirasjon" fra noen av Moskus' scripts. Input parametre: <deviceref>:<start>:<stop>:<time> Litt opplagt igrunn - men uansett vil dette endre devicen fra start til stopp, og bruke (tilnærmet) tid på det. (På grunn av litt avrundinger, så kan det ta noen sekunder mer eller mindre enn det du oppgir) For å ikke sende altfor mange kommandoer, så begrenser jeg meg per default til maks 4 kommandoer per sec (kan konfigureres) Noen spesialverdier: start = -1 - da leser jeg nåværende verdi, og dimmer til stoppverdi start = -2 - da leser jeg nåværende verdi, og øker/minker denne med stoppverdien Eksempler: 100:10:30:5 - skru dev 100 fra 10% til 30% (uavhengig av hva nåværende verdi er)- og bruke 5 sec på det 100:-1:30:5 - skru device fra nåværende verdi til 30% - og bruke 5 sec. 100:-2:-10:5 - endre device 100 med sluttverdien. Her er både positiv og negativ verdi tillatt - Om device 100 var på 35% før du startet scriptet, så vil den være på 25% etterpå. (og igjen - bruker 5 sec) Dette er ikke veldig foolproof - det er helt sikkert mulig å legge inn verdier som kræsjer hele scriptet - men så lang så fungerer det som jeg vil. Blant annet så tester det ikke om det finnes noe <deviceref>... (ikke ennå iallefall) Jeg kjører HomeSeer på Linux - ikke testet ut på en Windows-serveer (Og jeg har strengt tatt ikke planer om å gjøre det heller...) Jeg bruker det hovedsakelig til to ting: Styre utelyset mitt på en litt elegant måte, samt å skånsomt skru opp lyset på soverommet om morgenen. Kommentarer er mer en velkommen. Endringsforslag og "bug-reports" likeså
-
Nå er det mulig å styre en varmekilde med en vilkårlig temperatursensor og en vilkårlig varmekilde (av/på). Jeg har lovet i lengre tid å slippe script-pakken min, men det har vært litt mer utfordrende å lage en fungerende frontend. Nå har jeg imidlertid hoppet bukk over den problemstillingen og har flyttet innstillingene fra selve root-devicen og over i en tradisjonell ini-fil. Det gjør det lettere å endre alle innstillingene, selv om det er et stykke fra å være ideelt. Merk: Script-pakken er testet, men må vurderes som en beta-versjon. Egenskaper: "Auto", automatisk modus: Temperatur hentes ut fra et eller to oppsatte programmer. Programmene kan bruke ferdigdefinerte temperaturer eller egendefinerte. "Manual", manuell temperatur: justeres med nedtrekksboks og knapper for + og -) "High" og "Low" for hurtigvalg av forhåndsdefinerte "Schedule" og "AlternativeSchedule" kan byttes på f.eks. med Fridager.vb-scriptet (eller en vilkårlig annen On/Off virtuell device). Foreløpige begrensninger: Fungerer foreløpig ikke på Zee 1 eller 2. Begrensning i mono gjør at Enums ikke fungerer (visstnok). Jeg kan imidlertid unngå enums med litt omskriving (selv om det er veldig praktisk), så det kommer i en ny versjon. Nedtrekksboksen for manuell temperaturvalg setter ikke "Mode" til "Manual" automatisk (begrensning i scripting, kan ikke, så vidt jeg vet sette opp return CAPI-kall i script). + og - knappene gjør imidlertid dette helt fint. Oppsett 1. Først finn device Ref/IDene til både devicen for temperatursensoren og devicen for av/på bryteren til varmekilden (ovnen?). Device Ref står øverst på "Advanced"-tab'en etter at du har trykket på en device (eller i URLen som dukker opp når du holder musepekeren over linken til devicen). 2. Lag et event som du kaller "Termostat setup" (f.eks), sett trigger til "This Event is manually triggered". Legg til en Action som er "Run a Script", og trykk så på knappen "Edit, og skriv inn "VirtualThermostat.vb" (filnavnet er VELDIG viktig) og trykk OK. 3. Nå kollapser scriptet, så vi utvider det igjen og trykker på det røde flyet : . I scriptboksen (det store blanke feltet med Sub Main.... etc) fjerner du alt og kopierer inn scriptet under: ... og trykk på "Save Script" knappen nederst. HUSK: Trykk på "Save Script" knappen nederst. Gjort det? I "Sub or Function"-boksen skal det stå "Setup". I Parameter skal det stå: HeaterDeviceReference=1139,ExternalTemperatureSensorRef=74 ... der du bytter ut 1139 med dev-ref til av/på-bryteren og 74 med dev-ref til temperatursensoren. Da skal alt se slik ut: 4. Trykk på den blå pilen øverst på eventet for å sette i gang setup-rutinen. Da er vi snart ferdige. 5. Scriptet oppretter et Event (i Event-kategorien "Virtual Thermostat") som kjører scriptet hvert 5. minutt, og det er nesten helt riktig. Vi må bare justere et par ting. Åpne scriptet som ligger under "Virtual Thermostat". Gi det et litt mer beskrivende navn, så er det enklere å finne tilbake. 6. Utvid Run Script action'en, og deaktiver "Only allow a single instance to run at a time" (ellers er det jo bare en termostat som vil fungere) Hvis alt nå er vel, skal det se slik ut: 7. Personlig skrur jeg av logging på slike eventer: 7. ??? 8. Profit! Konfigurasjon I /Config-mappen din har det nå dukket opp en fil som heter "VirtualThermostat_nnn.ini" der nnn er device referansen til root'en (den samme som også navngir eventet over). Den vil se f.eks. slik ut: [Settings] ExternalTemperatureSensorRef=74 TemperatureCorrectionAddition=0 TemperatureCorrectionMultiplier=1 TemperatureOffset=0,3 Log=False HeaterDeviceReference=1139 TemperatureHigh=22 TemperatureLow=19 AlternativeScheduleDeviceReference=0 [Schedule] 6:00=High 8:0=Low 16:00=High 22:00=Low [AlternativeSchedule] 6:00=High 23:00=Low ... der vi kjenner igjen ExternalTemperatureSensorRef og HeaterDeviceReference som de vi satte opp i Setup-rutinen. De andre feltene har følgende forklaring: TemperatureCorrectionAddition=0 er hvor mye som legges til eller trekkes fra den faktiske temperatursensoren. Fint for kalibrering TemperatureCorrectionMultiplier=1 hvor mye temperatursensoren skaleres med fra den faktiske temperatursensoren. Fint for kalibrering. (1 = ingen skalering) TemperatureOffset er hvor langt ned under "Setpoint" temperaturen tillates å bli før varmekilden skrus på. Hvis Setpoint er satt til 22 grader, vil ikke ovnen bli satt på før temperaturen har sunket under 21,7 grader. TemperatureHigh og Low er selvforklarende. AlternativeScheduleDeviceReference er referanse til en enhet som bestemmer om det er "Schedule" eller "AlternativeSchedule" som skal brukes. Schedule og AlternativeSchedule: Her står klokkeslett (i stigende rekkefølge og uten ledende nuller) og tilhørende temperaturer. Med mindre du spesifiserer noe annet, vil kl 0:00 alltid begynne med "Low" temperaturvalg. Så da leser vi Schedule slik: Mellom kl 00 og 06 er det "Low" Mellom kl 6 og 8 er det "High" Mellom 8 og 16 er det "Low" Mellom 16 og 22 er det "High" Og fra 22 og utover er det "Low" Du kan spesifisere din egen temperatur istedenfor "High" og "Low" også, i tilfelle du vil ha en halv grad ekstra om kvelden. Da kan det f.eks. se slik ut: [Schedule] 6:00=High 8:0=Low 16:00=High 20:00=22,5 22:00=Low Pro tip: Du kan også sette opp Eventet til å kjøre på "device change" når temperatursensoren endrer verdi, istedenfor hvert 5. minutt (eller hvor ofte det å passer deg). Da kan det også være lurt å sette opp et par tilleggs-triggere til på bestemte klokkeslett eller andre hendelser, for det er jo ingen garanti at temperaturen endrer seg slik at scriptet trigges. Enjoy!
- 66 replies
-
- 13
-
Sub Main(ByVal parameters As Object) 'Moskus 2020 Dim devID As Integer = parameters.ToString Dim useHTMLtable As Boolean = True Dim url As String = "https://www.vg.no/spesial/2020/corona-viruset/data/norway-table-overview/" Dim source As String = "" Try Using client = New System.Net.WebClient Net.ServicePointManager.SecurityProtocol = Net.SecurityProtocolType.Tls12 client.Encoding = System.Text.Encoding.UTF8 source = client.DownloadString(url) End Using Catch ex As Exception hs.WriteLog("CoronaScript", "Net Feil: " & ex.Message) End Try If source = "" Then hs.WriteLog("CoronaScript", "Got no response from url: " & url) Exit Sub End If Dim json = Newtonsoft.Json.JsonConvert.DeserializeObject(Of Object)(source) Dim output As String = "" Try Dim confirmed As Integer = json("totals")("confirmed") If useHTMLtable Then output &= "<table border=0 cellspacing=0 cellpadding=0>" output &= "<tr><td><b>Totalt</b></td><td align='right'>" & json("totals")("confirmed") & "</td><td align='right'>" & json("totals")("dead") & "</td><td align='right'>" & json("totals")("recovered") & "</td></tr>" For i As Integer = 0 To json("cases").Count - 1 output &= "<tr><td>" & json("cases")(i)("name") & "</td><td align='right'>" & json("cases")(i)("confirmed") & "</td><td align='right'>" & json("cases")(i)("dead") & "</td><td align='right'>" & json("cases")(i)("recovered") & "</td></tr>" Next output &= "</table>" Else output &= "<b>Totalt: " & json("totals")("confirmed") & " / " & json("totals")("dead") & " / " & json("totals")("recovered") & "</b><br>" For i As Integer = 0 To json("cases").Count - 1 output &= "• " & json("cases")(i)("name") & ": " & json("cases")(i)("confirmed") & " / " & json("cases")(i)("dead") & " / " & json("cases")(i)("recovered") & "<br>" Next End If hs.SetDeviceString(devID, output, False) hs.SetDeviceValueByRef(devID, confirmed, True) Catch ex As Exception hs.WriteLog("CoronaScript", "Net Feil: " & ex.Message) End Try End Sub Trigger: Kjøres hvert 5. minutt Parameter: DeviceIDen til en virtuell device som skal holde verdien. Du kan endre variabelen "useHTMLtable" til False hvis du vil ha det i HStouch, for HStouch viser ikke pene HTML-tabeller... Oppdatert med data fra RapidAPI siden jeg ble lei av at VG er så dårlig på å oppdatere tallene sine: Sub Main(ByVal parameters As Object) 'Moskus 2020 Dim devID As Integer = parameters.ToString Dim url As String = "https://covid-193.p.rapidapi.com/statistics?country=Norway" Dim source As String = "" Try Using client = New System.Net.WebClient 'TLS1.2 and encoding (UTF8) Net.ServicePointManager.SecurityProtocol = Net.SecurityProtocolType.Tls12 client.Encoding = System.Text.Encoding.UTF8 'Headers client.Headers.Set("x-rapidapi-host", "covid-193.p.rapidapi.com") client.Headers.Set("x-rapidapi-key", "DIN_RAPIDAPI_KEY_HER") 'GET the url source = client.DownloadString(url) End Using Catch ex As Exception hs.WriteLog("CoronaScript", "Net Feil: " & ex.Message) End Try If source = "" Then hs.WriteLog("CoronaScript", "Got no response from url: " & url) Exit Sub End If Try Dim json = Newtonsoft.Json.JsonConvert.DeserializeObject(Of Object)(source) Dim confirmed As Integer = json("response")(0)("cases")("total") Dim output As String = "" output &= "<b>Aktive: " & json("response")(0)("cases")("active") & " (" & json("response")(0)("cases")("new") & ") " & "</b><br>" output &= "Totalt: " & json("response")(0)("cases")("total") & "<br>" output &= "Dødsfall: " & json("response")(0)("deaths")("total") & " (" & IIf(json("response")(0)("deaths")("new").ToString = "", "0", json("response")(0)("deaths")("new")) & ") " & "<br>" output &= "Testede: " & json("response")(0)("tests")("total") & "<br>" output &= "<i>Sist oppdatert: " & json("response")(0)("time") & "</i><br>" hs.SetDeviceString(devID, output, False) hs.SetDeviceValueByRef(devID, confirmed, True) Catch ex As Exception hs.WriteLog("CoronaScript Error", "Parsefeil: " & ex.Message) End Try End Sub Kjøres nå hver time, jeg vet ikke begrensningene hos RapidAPI.
-
Public Sub Main(ByVal input As Object) 'Moskus 2020 Dim device As Scheduler.Classes.DeviceClass Dim DE As Scheduler.Classes.clsDeviceEnumeration Dim counter As Integer = 0 Dim counterBelow100 As Integer Dim filter As String = "batter" 'tar da både "battery" og "batteri" hs.WriteLog("Battery", "Looking for battery devices...") DE = hs.GetDeviceEnumerator() Do While Not DE.Finished device = DE.GetNext If device.Device_Type_String(hs).ToLower.Contains(filter) OrElse device.DeviceType_Get(hs).Device_Type_Description.ToLower.Contains(filter) OrElse device.Name(hs).Contains(filter) Then Dim devName As String = device.Location2(hs) & ", " & device.Location(hs) & ", " & device.Name(hs) Dim devValue As Double = hs.DeviceValueEx(device.Ref(hs)) If devValue < 100 Then hs.WriteLog("Battery", "Device: " & devName & ", battery: " & devValue) counterBelow100 += 1 End If counter += 1 End If Loop hs.WriteLog("Battery", "Done! Found " & counter & " devices, " & counterBelow100 & " have levels below 100%.") End Sub Bare lagre som "GetBatteryLevels.vb" og kjør det. Det skrives til loggen.
-
- 5
-
Dette scriptet lar deg hente inn trafikkinformasjon fra EnTur. Finne reiseruter, IDer for "StopPlace" og "Quay" Å bruke scriptet er ikke så vanskelig. Det vanskelige er å finne IDene til stasjonene du vil spore. La oss si at jeg vil finne alle busser som går fra "Tasta Senter" (og mot Stavanger sentrum, men det kommer vi tilbake til) Gå til en-tur.no Tast inn stoppesteder til og fra Kopier URL'en fra nettleseren etter søket (f.eks. som denne) inn URLdecoder.org for å gjøre den lettere å lese. Finn "startID" og kopier ut strengen som begynner med "NSR:". For Tasta Senter er denne "NSR:StopPlace:28163" Oppdatering: Etter tips fra @Odd Are er det enklere å gå hit med brukernavn/passord guest/guest og hente QuayIDer og StopPlaceIDer derfra. Vel og bra! Nå vet vi at busstoppet ved Tasta Senter heter "NSR:StopPlace:28163". Men et busstopp kan faktisk ha flere plattformer, f.eks. en på hver side av veien. Det heter visst "Quay" på engelsk. Jeg er ikke interessert i begge sider av veien for kun en av dem har vanligvis trafikk mot sentrum. For å finne Quay, må vi bruke GraphQL-exploreren til EnTur (som dessverre ikke er like forseggjort som Tibber sin). Vi er interessert i denne spørringen som finner alle avganger for et stoppested, og vi må endre id: "NSR:StopPlace:28163" og avgangstiden (startTime:"2018-06-19T09:00:00+0200") til det riktige. I skrivende stund ser min spørring slik ut. Så går vi gjennom resultatene, vi skal prøve å finne riktig "Quay". Det første treffet er inneholder denne teksten: "destinationDisplay": { "frontText": "Tasta - Vardeneset" }, "quay": { "id": "NSR:Quay:48450" }, ... men en buss med "Tasta - Vardeneset" tar meg i feil retning! Ergo er "NSR:Quay:48450" ikke riktig. Det neste treffet inneholder dette: "destinationDisplay": { "frontText": "Stavanger" }, "quay": { "id": "NSR:Quay:48449" }, Jepp! Riktig! Altså kan vi filtrere på "NSR:Quay:48449" for å finne avganger fra "NSR:StopPlace:28163" som kun går mot Stavanger. Installasjon Du trenger en referanse til Newtonsoft.Json.dll for at scriptet skal fungere. Json er mye i bruk i dag, og siden jeg har oppdaget at Webclient nå er innebygget i HS3 (og superenkel å bruke), så er det bare å legge inn Json-støtte for scripting også. Lukk HS3. Åpne settings.ini Finn linjen som begynner med ScriptingReference= Vanligvis står det kun System.Core;System.Core.dll. Vi skal legge til Newtonsoft bak der. Hos meg (på Windows) skal linjen da se slik ut: ScriptingReferences=System.Core;System.Core.dll,Newtonsoft.Json;C:\Program Files (x86)\HomeSeer HS3\Bin\homeseer\Newtonsoft.Json.dll Lagre og start HS3 igjen. For Linux skal den muligens se slik ut, men du må sjekke plasseringen på /bin/homeseer/Newtonsoft.Json.dll selv. ScriptingReferences=System.Core;System.Core.dll,Newtonsoft.Json;/usr/local/HomeSeer/bin/homeseer/Newtonsoft.Json.dll Kopier scriptet under og lagre det som EnTur.vb. Etter massiv testing fra @Tor-Erik er vi ganske sikre på at det også kjører på Linux. EnTur.vb: Du må også lage deg noen devicer selv for å faktisk vise data. Dette gjør foreløpig ikke scriptet for deg. Den trenger ingen status values, men kanskje en enkel status Graphics for å ha et ikon (istedenfor Off/Dim/On-ikoner) Så trenger vi et event for å oppdatere teksten. Dette kan f.eks. kjøre hvert minutt. Parametre for funksjonen "CallsFromStopplace" er deviceID, stopplaceID, quayID (optional), antall_avganger (optional). Du kan ha flere script-kall i et event, hvis du har flere stopp, avganger, etc du vil kontrollere. Parametre for funksjonen "TripsBetweenStops" er deviceID, stopplaceID (fra), stopplaceID (til), antall_avganger (optional). Det er et enkelt ruteoppslag, fint fra større stasjoner (f.eks. "Stavanger") til et bestemt stoppested. DeviceValue i hver device er antall minutter til neste avgang. Kan brukes til automasjon. EDIT: Oppdatert juli 2019 pga. flytting av URL for EnTur APIet. Gjeldene URL er nå: https://api.entur.io/journey-planner/v2/graphql Oppdatert januar 2020 pga. bruk av TSL12.
-
CloneDevice.vb Speiler status fra en device over på flere andre. Praktisk for å f.eks. kunne skru av/på/dimme et helt rom samtidig. Parameter: 100|200+201+202 ... hvor 100 er master device (typisk taklampe) og 200-202 er andre devicer, Trigges typisk av master device set to any status. Sub Main(ByVal parms As String) '© Moskus Dim input() As String = Split(parms.ToString, "|") Dim control As String = input(0).ToString Dim devs() As String = Split(input(1).ToString, "+") Dim devicevalue As Double = hs.DeviceValueEx(control) Dim CAPIcontrol As HomeSeerAPI.CAPIControl = Nothing For Each cc As HomeSeerAPI.CAPIControl In hs.CAPIGetControl(control) If devicevalue = cc.ControlValue Then CAPIcontrol = cc Exit For End If Next For Each d as String In devs Dim dev As Scheduler.Classes.DeviceClass = hs.GetDeviceByRef(d) If CAPIcontrol.Label.ToLower.Contains("dim") Then If dev.Can_Dim(Nothing) Then Dim capi As HomeSeerAPI.CAPIControl = Nothing For Each cc As HomeSeerAPI.CAPIControl In hs.CAPIGetControl(d) If cc.Label = CAPIcontrol.Label Then capi = cc Exit For End If Next hs.CAPIControlHandler(capi) Else Dim off As HomeSeerAPI.CAPIControl = Nothing For Each cc As HomeSeerAPI.CAPIControl In hs.CAPIGetControl(d) If cc.Label.ToLower = "off" Then off = cc Exit For End If Next hs.CAPIControlHandler(off) End If Else Dim capi As HomeSeerAPI.CAPIControl = Nothing For Each cc As HomeSeerAPI.CAPIControl In hs.CAPIGetControl(d) If cc.Label = CAPIcontrol.Label Then capi = cc Exit For End If Next hs.CAPIControlHandler(capi) End If Next End Sub
-
Dette scriptet lar deg logge alle bevegelser til en device, slik at det blir enklere å se på web eller HStouch. Bevegelser (eller enhver hendelse) blir da logget slik. MotionLog.vb (ny) Public Sub Main(ByVal input As Object) Dim logDeviceRef As Integer = 1081 ' Update this Dim count As Integer = 9 'Maximum number of lines shown on the device - 1. 9 means 10 lines are shown Dim currentText As String = hs.DeviceString(logDeviceRef) currentText = currentText.Replace("<br>", "|") Dim lines() As String = currentText.Split("|") If lines.GetLength(0) < count Then count = lines.GetLength(0) Dim oldLines(count - 1) As String Array.Copy(lines, oldLines, count) 'Creating the device text Dim newText As String = Now.Date & " " & Now.ToLongTimeString & " - " & input.ToString If lines.GetLength(0) > 0 And lines(0) <> "" Then newText &= "<br>" 'Adding the previous lines newText &= String.Join("<br>", oldLines) 'Updating the device string hs.SetDeviceString(logDeviceRef, newText, True) 'hs.TriggerEvent("Restart SisteBeveglse timer") lines = Nothing oldLines = Nothing End Sub For hver bevegelsessensor har jeg da et event som blir trigget ved bevegelse (selvfølgelig! ), som i tillegg til å styre lys der det er nødvendig, kjører dette scriptet med sub Main og parameter med navnet på sensoren, som "Kjøkken" eller "Stue". I tillegg har jeg en timer som he ter "SisteBevegelse", som jeg resetter når dette skjer. Hvis du også vil bruke dette, må du opprette den timeren, lage et Event (som jeg har kalt "Restart SisteBevegelse timer" fordi det ikke finnes kode for å restarte den), og fjerne fnutten foran den nest siste linjen i koden. EDIT: Oppdatert slik at det blir penere i HStouch. EDIT2: Bruker arrays for å gjøre scriptet enklere. Burde nå kjøre på Linux uten problemer.
-
Problemet er som følger: Jeg overvåker fryser og ønsker å sende en melding i god tid før den har nådd 0 grader. Etter å ha opplevd ett par ganger at fryseren er blitt lukket, men ikke tett med tilsvarende dårlig kjøling så ønsker jeg å kunne varsle meg selv når man er på vei mot 0 grader ett stykke før den har nådd f.eks. -3 grader. Nå overvåker jeg kun på overstigning av -3 grader, men dette har en tendens å inntreffe lenge etter at jeg har dratt inn til jobb og siden jeg er pendler ett greit stykke (Moss - Oslo) så er det ikke å stikke fra jobben for å sjekke/lukke fryseren. Finnes det noe plugin eller script for å se om temperaturen er på vei opp utenom de vanlige "bølgene" som oppstår mellom hver gang kompressoren slår inn? Eller er dette noe man må "snekre" selv?
- 16 replies
-
- homeseer
- temperatur
-
(and 3 more)
Tagged with:
-
Tegneserier er gøy. Automatiske tegneserier er selvfølgelig enda gøyere. Tidligere var det bare å linke bildet på nettet, men VG ville gjøre det litt vanskeligere for oss. Men det lar seg ordne. Aller først trenger vi SP_ID'en din. Logg inn på VG (det holder med en gratis-konto), og trykk F12 (eller åpne Developer Console) Så finner du "Application" på menyen øverst, finner så cookies, og velger "www.vg.no". Dobbelttrykk på tekstfeltet etter "SP_ID" og kopier hele denne lange, uforståelige teksten til et sted. NB! Dette scriptet omfatter sletting av filer, og kan potensielt gå ad undas. Det er selvfølgelig testet en del av meg, men som alltid: Ta backup først! Scriptet er her: Tegneserie.vb Sub Main(ByVal input As Object) 'Moskus 2019 'Parametre: device_ID|Tegneserie 'Serie-alternativer: Pondus, Lunch, Hjalmar, Tegnehanne Dim devID As String = input.ToString.Split("|")(0) Dim serie As String = input.ToString.Split("|")(1) Dim deleteFiles As Boolean = True Dim SP_ID As String = "DIN_LANGE_SPID_STRENG_HER" Dim directoryName As String = hs.GetAppPath & "/html/images/Tegneserier/" 'Check if "Tegneserier" exits If (Not System.IO.Directory.Exists(directoryName)) Then System.IO.Directory.CreateDirectory(directoryName) 'Delete local files If deleteFiles Then For Each deleteFile As String In System.IO.Directory.GetFiles(directoryName, serie.ToLower & "*.*", System.IO.SearchOption.TopDirectoryOnly) System.IO.File.Delete(deleteFile) Next End If Dim remoteFile As String = "" Dim filename As String = serie.ToLower & "_" & Now.Date.ToString("yyMMdd") & ".jpg" Dim localFile As String = hs.GetAppPath & "/html/images/Tegneserier/" & filename Dim dateFormat As String = Now.Year & "-" & Now.Month.ToString("00") & "-" & Now.Day.ToString("00") Select Case serie.ToLower Case = "pondus" remoteFile = "https://www.vg.no/tegneserier/api/images/pondus/" & dateFormat Case = "lunch" remoteFile = "https://www.vg.no/tegneserier/api/images/lunch/" & dateFormat Case = "hjalmar" remoteFile = "https://www.vg.no/tegneserier/api/images/hjalmar/" & dateFormat Case = "tegnehanne" remoteFile = "https://www.vg.no/tegneserier/api/images/tegnehanne/" & dateFormat End Select If remoteFile <> "" Then Try Using client As New System.Net.WebClient Net.ServicePointManager.SecurityProtocol = Net.SecurityProtocolType.Tls12 client.Headers.Add(Net.HttpRequestHeader.Cookie, "SP_ID=" & SP_ID) client.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0") client.DownloadFile(remoteFile, localFile) client.Dispose() End Using Catch ex As Exception hs.WriteLog("Tegneserier", "Ex: " & ex.ToString) End Try Dim dateValue As Integer = CInt(Now.Date.ToString("yyMMdd")) hs.SetDeviceString(devID, "<img src='/images/HomeSeer/status/custom.gif' />", True) hs.SetDeviceString(devID, "<img src='./images/Tegneserier/" & filename & "' width='300px' />", False) hs.SetDeviceValueByRef(devID, dateValue, True) Else hs.WriteLog("Tegneserie", "RemoteFile ikke spesifisert for tegneserie: " & serie) End If End Sub Du legger inn SP_ID-strengen din istedenfor "DIN_LANGE_SPID_STRENG_HER". I tillegg må du lage en device pr. tegneserie du er interessert i. Som i nyhetsscriptet er dette en "Status Only" device. Så er det bare å sette opp eventet. Tegneseriene blir oppdatert kl. 08:00, så 08:15 er sikkert et bra tidspunkt. Kun ukedager og lørdager. Huk av "Wait for Script to finish" og "Only allow singe instance". Så repeter for hver tegneserie. Parameter er dev_ID|Tegneserie, f.eks. 3689|Pondus. ... som gir oss: Bredden er satt til 300px for at hele tegneserien skal dukke opp i Device Management, men dette er ikke en begrensning i f.eks. HStouch.
-
Nyheter er viktig, og din bolig burde vite hva som skjer. HStouch kommer med en RSS-leser, men den støtter ikke norske tegn, og fungerer bare når den vil. Ettersom jeg ble lei av det, skrev jeg et lite script for å hente frem nyheter. NewsReader.vb Sub Main(ByVal parameters As Object) 'Moskus 2019 Dim devID As Integer = parameters.ToString.Split("|")(0) Dim url As String = "https://api.rss2json.com/v1/api.json?rss_url=" & System.Net.WebUtility.HtmlEncode(parameters.ToString.Split("|")(1)) Dim source As String = "" Try Using client As New System.Net.WebClient Net.ServicePointManager.SecurityProtocol = Net.SecurityProtocolType.Tls12 client.Encoding = System.Text.Encoding.UTF8 source = client.DownloadString(url) End Using Catch ex As Exception hs.WriteLog("NewsReader Error", "Net Feil: " & ex.Message) End Try If source = "" Then hs.WriteLog("NewsReader Error", "Got no response from url: " & url) Exit Sub End If Try Dim json = Newtonsoft.Json.JsonConvert.DeserializeObject(Of Object)(source) Dim output As String = "" For i As Integer = 0 To 4 output &= "• <b>" & json("items")(i)("title") & "</b><br>" output &= json("items")(i)("description") & "<br><br>" Next hs.SetDeviceString(devID, output, True) Catch ex As Exception hs.WriteLog("NewsReader Error", "Net Feil: " & ex.Message) End Try End Sub HomeSeer trenger en referanse til Newtonsoft.Json.Dll, det kan du sette opp ved å lese under "Installasjon" i denne tråden: https://www.hjemmeautomasjon.no/forums/topic/4338-script-enturvb-få-inn-data-fra-entur/ Du trenger en virtuell device per nyhetskilde du vil ha. Ingen controller er viktig, velg "Status Only device" og "Do not log commands from this device". Så lager du et event. Det kan trigge hvert 15. minutt. Og så legger du til en kjøring av NewsReader.vb for hver nyhetskilde du ønsker deg. Parameter for scriptet er "DEV_ID|http://nyhetskilde.com/rss/", altså device ID, en "pipe" | og kilden. Huk av "Wait for script to finish" og "Only allow a single instance" Da blir resultatet dette: Her er noen nyhetskilder: https://www.aftenbladet.no/rss https://www.aftenposten.no/rss https://www.nrk.no/toppsaker.rss https://www.dagbladet.no/rss/ https://www.vg.no/rss/feed/?categories=1068&limit=10&format=rss&private=1 - sjekk https://vg.no/rss for å sette opp din egen feed.
-
- 4
-
De som har lest HomeSeer-skolen vet at jeg er veldig opptatt av å holde orden i systemet sitt. Det er fordi da er det så mye enklere å finne frem når man skal automatisere. Det er lett å huske hva "Node 11 Switch Multilevel 1" er når man bare har 11 noder, men når man har mange er det selvfølgelig helt umulig. I HomeSeer er det lett å tilordne rom og etasje til enhetene dine, men det er tungvindt å gi selve devicene noe mer fornuftig valg. Jeg navngir enheter med "Enhet, device_type", slik at det f.eks. er "Taklys, Switch Multilevel 1" eller "Taklys, Power", og det har jeg frem til nå gjort manuelt fordi jeg legger til en og en node. Men tidligere i vår satte jeg opp et helt hus på et par dager, på over 60 noder. Da tar det altfor lang tid å gjøre det manuelt, og et script var på sin plass. Scriptet gjør at dette: ... enkelt kan forandres til dette (etter å ha også gitt dem nye etaskjer og rom): ... og dermed kan man med litt sjuling av "unødvendige enheter" ende opp med noe enklere: Det fungerer også på andre sensorer, bl.a. bevegelsessensorer og magnetbrytere. Før: Etter: Bruk Måten det gjøres på er at root-devicen navngis med navnet du har tenkt å bruke og med et komma og Root bak, f.eks. "Taklys, Root (123)" (jeg har også begynt å sette nodenummeret i parentes bak Root). Så kjøres scriptet med Root Device ID som parameter, sub/function må settes til "RenameDevices". RenameDevices.vb Sub RenameDevices(input As String) 'Moskus 2019 Dim rootRef As Integer = input Dim rootDevice As Scheduler.Classes.DeviceClass = hs.GetDeviceByRef(rootRef) rootDevice.MISC_Set(hs, HomeSeerAPI.Enums.dvMISC.NO_LOG) If Not rootDevice.Name(hs).Contains("Switch") Then rootDevice.MISC_Clear(hs, HomeSeerAPI.Enums.dvMISC.AUTO_VOICE_COMMAND) Dim rootName As String = rootDevice.Name(hs) Dim prefix As String = rootName.Substring(0, rootName.IndexOf(",")).Trim hs.WriteLog("RenameDevices", "Starting with prefix: " & prefix) Dim i As Integer 'For i = (rootRef + 1) To endRef For Each i In rootDevice.AssociatedDevices(hs) Dim device As Scheduler.Classes.DeviceClass = hs.GetDeviceByRef(i) device.Name(hs) = prefix + ", " + device.Name(hs) device.MISC_Set(hs, HomeSeerAPI.Enums.dvMISC.NO_LOG) If Not device.Name(hs).Contains("Switch") Then device.MISC_Clear(hs, HomeSeerAPI.Enums.dvMISC.AUTO_VOICE_COMMAND) Next hs.SaveEventsDevices() hs.WriteLog("RenameDevices", "Done renaming " & prefix) End Sub
-
Inspirert til å løse @toonwolf sitt problem. Se under: Sub Add(ByVal inputArgs As String) 'Input: RootReference;place;NewPin 'Example: 342;65;1234 hs.WriteLog("Add user", "Adding user...") Dim interfaceID As String = hs.GetINISetting("Interfaces", "IFace_0_Unique", "", "Z-Wave.ini") hs.WriteLog("Add user", "InterfaceID: " & interfaceID) Dim rootDeviceRef As Integer = inputArgs.Split(";")(0) Dim place As Integer = inputArgs.Split(";")(1) Dim PINnumber As Integer = inputArgs.Split(";")(2) Dim PINstring As String = PINnumber.ToString("0000") Dim nodeNumber As String = ZwaveUtil_GetNodeIdByRef(rootDeviceRef) hs.WriteLog("Removing user", "Node number: " & nodeNumber) Dim configResult = hs.PluginFunction("Z-Wave", "", "AddUserCodePin", {nodeNumber, place.ToString, PINstring, "TEST-user", interfaceID}) hs.WriteLog("Add user", "Done with result " & configResult.ToString) End Sub Sub Remove(ByVal inputArgs As String) 'Input: RootReference;place 'Example: 342;65 hs.WriteLog("Removing user", "Removing user...") Dim interfaceID As String = hs.GetINISetting("Interfaces", "IFace_0_Unique", "", "Z-Wave.ini") hs.WriteLog("Removing user", "InterfaceID: " & interfaceID) Dim rootDeviceRef As Integer = inputArgs.Split(";")(0) Dim place As Integer = inputArgs.Split(";")(1) Dim nodeNumber As String = ZwaveUtil_GetNodeIdByRef(rootDeviceRef) hs.WriteLog("Removing user", "Node number: " & nodeNumber) Dim ConfigResult = hs.PluginFunction("Z-Wave", "", "RemoveUserCodePin", {nodeNumber, place.ToString, interfaceID}) hs.WriteLog("Removing user", "Done with result " & ConfigResult.ToString) End Sub Public Function ZwaveUtil_GetNodeIdByRef(ByVal deviceId As Integer) As Integer Dim nodeId As Integer = -1 If (deviceId > 0) Then Dim device As Scheduler.Classes.DeviceClass = hs.GetDeviceByRef(deviceId) If (device IsNot Nothing) Then Dim pdata As HomeSeerAPI.PlugExtraData.clsPlugExtraData = device.PlugExtraData_Get(hs) If (pdata IsNot Nothing) Then nodeId = pdata.GetNamed("node_id") End If End If Else Throw New System.Exception("Device not found: " + deviceId) End If Return nodeId End Function
-
Se neste post for oppdatert versjon.