Av
Moskus
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.
Anbefalte innlegg
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.