Gå til innhold
  • Bli medlem

SCRIPT: Twinkly.vb - Juletrelys med forhåndsdefinerte og egne animasjoner


Moskus
 Del

Anbefalte innlegg

Twinkly.gif

 

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:
 

Spoiler

 



'Moskus 2019
    Const IP As String = "192.168.0.166"
    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)
        Dim cmd As String = input(1)
        If DoCmd(cmd) Then hs.SetDeviceString(deviceRef, cmd, True)
    End Sub

    Public Function DoCmd(ByVal command As String) 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)

        SetMode(command)
        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", 1, "Twinkly.vb", "ButtonPress", "Movie", 1, 1, 1))
            hs.WriteLog("Twinkly", "Added button 2: " & hs.DeviceScriptButton_AddButton(devID, "Effect", 2, "Twinkly.vb", "ButtonPress", "Effect", 1, 2, 1))
            hs.WriteLog("Twinkly", "Added button 3: " & hs.DeviceScriptButton_AddButton(devID, "Demo", 3, "Twinkly.vb", "ButtonPress", "Demo", 1, 3, 1))
            hs.WriteLog("Twinkly", "Added button 4: " & hs.DeviceScriptButton_AddButton(devID, "RT", 4, "Twinkly.vb", "ButtonPress", "RT", 2, 1, 1))
            hs.WriteLog("Twinkly", "Added button 5: " & hs.DeviceScriptButton_AddButton(devID, "Off", 0, "Twinkly.vb", "ButtonPress", "Off", 2, 2, 1))
        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>
    ''' 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

 

 

Da får du en device som dette:

image.png

Gå inn på Devicen, og gå til Advanced.

 

Legg så IP-adressen til Twinkly-lenken inn under "Device Type (String)":

image.png

 

... og siden vi endrer Device Types, må vi huske å vise alle etter på:

image.png

 

 

Den nye versjonen støtter altså flere lenker på samme script, man slipper å lage kopier av scriptet hvis man har flere lenker. :) 

  • Like 5
  • Thanks 2
Lenke til kommentar
Del på andre sider

Hei,

Takk for at du deler.  Jeg har ingen kompetanse på VBscript og får det ikke til å kjøre hos meg. Kan det være at dette scriptet kun kjører godt i Windows?

Jeg kjører HS3 i Linux.

 

Dec-21 09:58:29   Error Compiling script /HomeSeer/scripts/Twinkly.vb: 'i'.
Dec-21 09:58:29   Error Compiling script /HomeSeer/scripts/Twinkly.vb: 'Newtonsoft' is not declared. It may be inaccessible due to its protection level.
Dec-21 09:58:29   Error Compiling script /HomeSeer/scripts/Twinkly.vb: 'Newtonsoft' is not declared. It may be inaccessible due to its protection level.
Dec-21 09:58:29   Error Compiling script /HomeSeer/scripts/Twinkly.vb: 'Newtonsoft' is not declared. It may be inaccessible due to its protection level.
Dec-21 09:58:29   Error Compiling script /HomeSeer/scripts/Twinkly.vb: 'ex'.
Dec-21 09:58:29   Error Compiling script /HomeSeer/scripts/Twinkly.vb: 'Newtonsoft' is not declared. It may be inaccessible due to its protection level.
Dec-21 09:58:29   Error Compiling script /HomeSeer/scripts/Twinkly.vb: 'Newtonsoft' is not declared. It may be inaccessible due to its protection level.
Dec-21 09:58:29   Error Compiling script /HomeSeer/scripts/Twinkly.vb: 'ex'.
Dec-21 09:58:29   Error Compiling script /HomeSeer/scripts/Twinkly.vb: 'Newtonsoft' is not declared. It may be inaccessible due to its protection level.
Dec-21 09:58:29   Error Compiling script /HomeSeer/scripts/Twinkly.vb: 'Newtonsoft' is not declared. It may be inaccessible due to its protection level.
Dec-21 09:58:29   Error Compiling script /HomeSeer/scripts/Twinkly.vb: Function without an 'As' clause; return type of Object assumed.
Dec-21 09:58:29   Error Compiling script /HomeSeer/scripts/Twinkly.vb: Variable declaration without an 'As' clause; type of Object assumed.
Dec-21 09:58:29   Error Compiling script /HomeSeer/scripts/Twinkly.vb: Namespace or type specified in the Imports 'System.Core' doesn't contain any public member or cannot be found. Make sure the namespace or the type is defined and contains at least one public member. Make sure the imported element name doesn't use any aliases.
Dec-21 09:58:29   Event Running script in background: /HomeSeer/scripts/Twinkly.vb("Setup")

 

Lenke til kommentar
Del på andre sider

59 minutter siden, einarli skrev:

Kan det være at dette scriptet kun kjører godt i Windows?

Jeg kjører HS3 i Linux.

Det er ikke testet på Linux, men programmert for å kunne støtte det. (Ellers er det en del forenklinger jeg hadde valgt)

 

 

Men det er en ting jeg har glemt å nevne! Sorry! :( 

Du trenger en referanse til Newtonsoft.Json.Dll. Beskrivelsen om hvordan du legger til det finnes under "Installasjon" for EnTur.vb-scriptet.

Lenke til kommentar
Del på andre sider

Har ikke fått testet scriptet enda, men det så såppas interessant ut at jeg måtte innom kjell og handle en twinkly lenke like før jul.

Har lekt litt med den kun via appen, og er forsåvidt ganske imponert over lysene.

 

Nå lurer jeg imidlertid litt på hva knappene til devicen gjør?  jeg ser referanse til i koden til movie, men hva med RT/Effect/Demo ?

Kan man lage egne knapper til egendefinerte scener? Og så lurer jeg på hvor i konfigen du peker en devicebutton til hvilket script/funksjon i scriptet.

Lenke til kommentar
Del på andre sider

2 timer siden, Gjelsvik skrev:

Nå lurer jeg imidlertid litt på hva knappene til devicen gjør?  jeg ser referanse til i koden til movie, men hva med RT/Effect/Demo ?

Kan man lage egne knapper til egendefinerte scener?

Man kan pr. nuh ikke lage egendefinerte scener. For det er litt plunder. Man må sniffe trafikken og lagre det, sammen med noen innstillinger. Jeg hadde håpet at det var enklere enn det, men sånn flaks har vi ikke hatt til nå...

 

RT er faktisk bare "Pause". "Effekt" er en innebygget "movie". "Demo" er jeg faktisk ikke helt sikker på hva gjør... :P

 

2 timer siden, Gjelsvik skrev:

Og så lurer jeg på hvor i konfigen du peker en devicebutton til hvilket script/funksjon i scriptet.

Sjekk sub'en "AddDeviceButtons".

Lenke til kommentar
Del på andre sider

10 timer siden, einarli skrev:

Det er også fra Twinkly, men ikke RGB LED,  De har varme nyanser fra helt hvit til veldig varmt lys og mulighet for dimming.

 

OK, de har jeg ikke kontroll på. Scriptet er bare basert på de APIene som andre har funnet frem til med reverse engineering.

 

Men noen kan sikkert sniffe seg frem til disse også... :)

Lenke til kommentar
Del på andre sider

Litt off topic:

En DIY versjon av Twinkly.

Hvis en har en nodeMCU og noen ledløkker liggende så kan vel wled gjøre noe tilsvarende https://github.com/Aircoookie/WLED

Er klar for både MQTT & E1.31

 

Jeg hadde store planer i år, men det er vist veto mot RGB på Juletreet...

 

Integrasjon til Home Assistant (!HA) er klar ser det ut til https://selfhostedhome.com/christmas-tree-lights-using-wled/

 

Lenke til kommentar
Del på andre sider

On 27/12/2019 at 11:59, Moskus said:

Man kan pr. nuh ikke lage egendefinerte scener. For det er litt plunder. Man må sniffe trafikken og lagre det, sammen med noen innstillinger. Jeg hadde håpet at det var enklere enn det, men sånn flaks har vi ikke hatt til nå...

 

RT er faktisk bare "Pause". "Effekt" er en innebygget "movie". "Demo" er jeg faktisk ikke helt sikker på hva gjør... :P

 

Sjekk sub'en "AddDeviceButtons".

 Så det eneste du kan gjøre via dette scriptet er basicly pause en animasjon som er startet fra appen?

 

"movie" er ikke et begrep jeg kjenner igjen noe sted fra twinkly appen.

Lenke til kommentar
Del på andre sider

2 timer siden, Gjelsvik skrev:

 Så det eneste du kan gjøre via dette scriptet er basicly pause en animasjon som er startet fra appen?

Du kan starte valgt effekt fra app'en (som er det som heter "movie"), du kan kjøre en demo (dvs "effect"), du kan pause ("RT") og skru den av.

Lenke til kommentar
Del på andre sider

  • 10 måneder senere...

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.

Gjest
Skriv svar til emnet...

×   Du har limt inn tekst med formatering.   Lim inn uten formatering i stedet

  Du kan kun bruke opp til 75 smilefjes.

×   Lenken din har blitt bygget inn på siden automatisk.   Vis som en ordinær lenke i stedet

×   Tidligere tekst har blitt gjenopprettet.   Tøm tekstverktøy

×   Du kan ikke lime inn bilder direkte. Last opp eller legg inn bilder fra URL.

 Del

  • Lignende innhold

    • Av Join
      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. 
    • Av Moskus
      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.
    • Av Moskus
      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  
    • Av Moskus
      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.

       
       
    • Av Moskus
      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.
×
×
  • Opprett ny...