Gå til innhold

HSTouch XML hack'ing


Anbefalte innlegg

Selv om Powerpoint2HSTouch Utilityen min streemliner grafikk produksjonen ganske bra, kvier jeg meg fremdeles for å virkelig å eksplodere i begeistret HSTouch produksjon der jeg kan styre alt fra alle (HSTouch) devicene jeg har i hus.

 

Det er rett og slett for mye KJEDELIG, repetiv point og klikk arbeid :(

 

Jeg har defor startet opp produksjonen av en "alternativ" HSTouch editor, dvs egentlig en HSTouch XML hack'er (for det er bare noen få bestemte ting jeg ønsker å gjøre MYE av)

 

Tanken er å kunne hente Powerpoint 3D button grafikk rett inn og så kunne drag-droppe en HS3 Device (eller en Event) på den for å skape en:

 

- Status Button med, 2 status grafikk, Status tracking og Toggle On/Off på Button release

 

- En slider

 

- En "Execute" button som kaller opp en Event

 

Dette vil dekke 90 % av behovene mine for styring.

 

Den som vil kan (straks) får være med å teste, MEN:

 

Moskus:

Jeg trenger kode for, i en Windows Form i en standalone .exe fil kunne vise:

- Alle Floors i en drop-down Listbox

- Alle Devicer (på Dette floor) med navn og DevRef

- Alle Eventer på samme måte

 

Help me Please, - så sparer du meg for MASSE tid...

Lenke til kommentar
Videoannonse
Annonse

Jeg skal være ærlig på det: Jeg vet ikke hvordan man kobler seg til HS3 med et ekstern, standalone program. I HS2 kunne jeg få det til, men jeg har ikke undersøkt i HS3. Jeg VET at det ikke er samme fremgangsmåte.

 

Men alternativt er det bare å laste ned sample-plugin'en. Den kjører faktisk som en separat prosess og har full tilgang til HS3 (det er slik plugin-strukturen er i HS3, veldig elegant). Du kan til og med koble opp "remote", dvs. fra en annen maskin. Se Main() i main.vb:

    Sub Main()
        Dim IP As String = "127.0.0.1"
        Dim args As System.Collections.ObjectModel.ReadOnlyCollection(Of String) = My.Application.CommandLineArgs
        For Each s In args
            Debug.WriteLine(s)
        Next

        Dim arg As String
        For Each arg In args
            Dim ch(0) As String
            ch(0) = "="
            Dim parts() As String = arg.Split("=") 'arg.Split(ch, StringSplitOptions.None)
            Select Case parts(0).ToLower
                Case "server"
                    IP = parts(1)

                Case "instance"
                    Try
                        Instance = parts(1)
                    Catch ex As Exception
                        Instance = "Remote"
                    End Try
            End Select
        Next
        If IP = "127.0.0.1" Then Instance = "Local"

        AppAPI = New HSPI

        Console.WriteLine("Connecting to server at " & IP & "...")
        client = ScsServiceClientBuilder.CreateClient(Of IHSApplication)(New ScsTcpEndPoint(IP, 10400), AppAPI)
        clientCallback = ScsServiceClientBuilder.CreateClient(Of IAppCallbackAPI)(New ScsTcpEndPoint(IP, 10400), AppAPI)

        Dim Attempts As Integer = 1

TryAgain:
        Try
            client.Connect()
            clientCallback.Connect()

            host = client.ServiceProxy
            Dim APIVersion As Double = host.APIVersion  ' will cause an error if not really connected

            callback = clientCallback.ServiceProxy
            APIVersion = callback.APIVersion  ' will cause an error if not really connected
        Catch ex As Exception
            Console.WriteLine("Cannot connect attempt " & Attempts.ToString & ": " & ex.Message)
            If ex.Message.ToLower.Contains("timeout occurred.") Then
                Attempts += 1
                If Attempts < 6 Then GoTo TryAgain
            End If

            If client IsNot Nothing Then
                client.Dispose()
                client = Nothing
            End If
            If clientCallback IsNot Nothing Then
                clientCallback.Dispose()
                clientCallback = Nothing
            End If
            wait(4)
            Return
        End Try

        Console.WriteLine("Almost connected, trying to get references...")
        wait(1)
        Try
            ' create the user object that is the real plugin, accessed from the pluginAPI wrapper
            callback = callback
            hs = host
            ' connect to HS so it can register a callback to us
            host.Connect(IFACE_NAME, Instance)
            'Console.WriteLine("Connected, waiting to be initialized...")
            Console.WriteLine("Connected!")
            Do
                Threading.Thread.Sleep(30)
            Loop While client.CommunicationState = HSCF.Communication.Scs.Communication.CommunicationStates.Connected And Not bShutDown
            If Not bShutDown Then
                oPlugin.ShutdownIO()
                Console.WriteLine("Connection lost, exiting")
            Else
                Console.WriteLine("Shutting down plugin")
            End If
            ' disconnect from server for good here
            client.Disconnect()
            clientCallback.Disconnect()
            wait(2)
            End
        Catch ex As Exception
            Console.WriteLine("Cannot connect(2): " & ex.Message)
            wait(2)
            End
            Return
        End Try

    End Sub
Lenke til kommentar
- Tok meg en time å få eksemplet opp å kjøre
(Gamle dll'er i referansene :( )
- tok en time til å gi opp å starte en Form1 fra en plugin.
(Var i ferd med å gi opp hele greia)
- En time til og jeg kunne skrive i loggen med ett vanlig "hs.writelog(" MENS pluginen initialiserte seg... hm..
- en halv time til og jeg skjønte at jeg kunne åpne en connection, lese det jeg ønsket og så lukke igjen.
-40 minutter til og jeg hadde strippet bort alt det unødvenlige og lempet det over i en ren Windows app.
Konklusjon:
Jeg trenger ikke en plugin for å lese devicer fra en exe !!!
Det holder med 3 linjer:
        Dim sIp As String = "192.168.232.9"
        client = ScsServiceClientBuilder.CreateClient(Of IHSApplication)(New ScsTcpEndPoint(sIp, 10400))

        Try
            client.Connect()
            hs = client.ServiceProxy

            hs.WriteLog("Powerpoint2HSTouch", "Reading Devices")
osv..

Jeg er VELDIG fornøyd med meg selv!

Dette var et skikkelig gjennombrudd for meg

 

Lenke til kommentar

Konklusjon:

Jeg trenger ikke en plugin for å lese devicer fra en exe !!!
Det holder med 3 linjer:
        Dim sIp As String = "192.168.232.9"
        client = ScsServiceClientBuilder.CreateClient(Of IHSApplication)(New ScsTcpEndPoint(sIp, 10400))

        Try
            client.Connect()
            hs = client.ServiceProxy

            hs.WriteLog("Powerpoint2HSTouch", "Reading Devices")
osv..

Jeg er VELDIG fornøyd med meg selv!

Dette var et skikkelig gjennombrudd for meg

Flott! :)

 

... men det burde ikke være vanskelig å bytte fra Console til Forms. Jeg gjør det rett som det er (dog, ikke forsøkt med plugins enda).

Lenke til kommentar

... men det burde ikke være vanskelig å bytte fra Console til Forms. Jeg gjør det rett som det er (dog, ikke forsøkt med plugins enda).

 

 

Men det gjorde jeg i går!

Koden over er fra en Windows form der jeg hadde en scrollbar som dimmet lyset...

Lenke til kommentar

Hehehe! Stilig! :D

 

Husk å bruker "registercallback", så kan du få feedback også når du dimmer lyset fra andre steder. ;)

Vei nå var det ikke en Windows versjon av HS jeg skulle lage, men joda om jeg laget en Plugin med callback ville nok det kunne funke.

 

Men da roter jeg meg tilbake opp i en del threading problematikk som jeg ikke er helt stø i.

 

Nå gjelder det å putte korrekte DevRefer inn i HsTouch XML filer :)

Lenke til kommentar

Ja, angående det. Jeg har kun hatt bruk for device'ref, ikke Eventer, så jeg har forenklet din originale oppskrift.

Public Class ConvertHStouchToHS3
    Public Sub Main(ByVal input As Object)
        Dim filename As String = "\\NAS1\Software\HomeSeer\HStouch\PC_stor"

        'Define what we are looking for in the HStouch project
        Dim hstouch_xml As New List(Of String)
        ' Alle Select trackinger
        hstouch_xml.Add("HS_Status_Ref_Sel")
        ' Alle DeSelect trackinger
        hstouch_xml.Add("HS_Status_Ref_DeSel")
        ' When press / Trig HS Dev
        hstouch_xml.Add("ActDvEvRef")
        ' When release / Trig HS Dev
        hstouch_xml.Add("ActDvEvRef")
        ' When press / Trig HS Event
        hstouch_xml.Add("ActDvEvRef")
        ' When release / Trig HS Event
        hstouch_xml.Add("ActDvEvRef")

        'Read the XML file for the HStouch project
        Dim lines As New List(Of String)
        Dim sr As New IO.StreamReader(filename & ".xml", System.Text.Encoding.UTF8)
        Do While Not sr.EndOfStream
            lines.Add(sr.ReadLine)
        Loop
        sr.Close()
        sr.Dispose()


        'Load the file with the HS2 and HS3 references
        Dim devs As New List(Of MyDevice)
        sr = New IO.StreamReader("HS2 to HS3.txt")
        Do While Not sr.EndOfStream
            devs.Add(New MyDevice(sr.ReadLine))
        Loop
        Debug.WriteLine("Device count: " & devs.Count)

        'Output holder
        Dim output As New List(Of String)

        'Searching for HS2 references and replacing it with HS3 references
        Dim counter As Integer = 0
        For Each l In lines
            Debug.WriteLine("Line " & counter & " / " & lines.Count)
            counter += 1

            Dim matchfound As Boolean = False
            For Each x In hstouch_xml
                If l.ToLower.Contains(x.ToLower) Then
                    Dim start As Integer = l.IndexOf(">")
                    Dim slutt As Integer = l.IndexOf("<", start)
                    Dim hs2ref As Integer = l.Substring(start + 1, slutt - start - 1)

                    If hs2ref > 0 Then
                        Dim node As MyDevice = MyDevice.FindNode(hs2ref, devs)
                        If node IsNot Nothing Then
                            output.Add(l.ToString.Replace(node.HS2ref, node.HS3ref))
                            matchfound = True
                            Exit For
                        End If
                    End If
                End If
            Next
            If Not matchfound Then output.Add(l.ToString)
        Next

        Dim sw As New IO.StreamWriter(filename & "_HS3.xml", False, System.Text.Encoding.UTF8)
        For Each s In output
            sw.WriteLine(s)
        Next
        sw.Close()
        sw.Dispose()


    End Sub



    Public Class MyDevice
        Public Property HS2ref As Integer
        Public Property HS3ref As Integer
        Public Property HS2code As String
        Public Property Name As String
        Public Property Location As String
        Public Property Location2 As String
        Public Property DeviceType As String

        Public Sub New(ByVal line As String)
            Dim input() As String = line.Split(ControlChars.Tab)

            HS3ref = input(0)
            HS2ref = input(1)
            Location2 = input(2)
            Location = input(3)
            Name = input(4)
            DeviceType = input(5)
        End Sub

        Public Sub New(ByVal _Node As Integer, _Name As String, _Location As String, _Location2 As String)
            HS2ref = _Node
            Location2 = _Location2
            Location = _Location
            Name = _Name
        End Sub

        Public Overrides Function ToString() As String
            Return HS2ref & ControlChars.Tab & Location2 & ControlChars.Tab & Location & ControlChars.Tab & Name & ControlChars.Tab & DeviceType
        End Function

        Public Function ToSaveString() As String
            Return HS3ref & ControlChars.Tab & HS2ref & ControlChars.Tab & Location2 & ControlChars.Tab & Location & ControlChars.Tab & Name & ControlChars.Tab & DeviceType
        End Function

        Public Shared Function FindNode(ByVal _ref As Integer, ByVal lst As List(Of MyDevice)) As MyDevice
            For Each d In lst
                If d.HS2ref = _ref Then Return d
            Next
            Return Nothing
        End Function
    End Class
End Class
Lenke til kommentar
Vel jeg foretrekker å navigere XML dokumenter med system.xml.xmldocument og synes objekter er enklere enn en stream men hver sin smak.
Kodinge går framover og jeg kan snart vise noe kjørbart men først trenger jeg litt LINQ hjelp (og det elsker jo du ;) )
Jeg leser alle devicene inn i en list som denne:
    Public AllDevs As New List(Of Devs)


    Public Class Devs
        Public Property refnr As String
        Public Property Interf As String
        Public Property Location As String
        Public Property Location2 As String
        Public Property Name As String
    End Class

Jeg har 4 Dropdown listboxer:

cboInterface

cboLocation2 (Floor)

cboLocation (Room)

cboDevice

 

En bruker de tre øverste til å filtrere hva som er i den nederste og så kan en dra den nederste og droppe den på en kontroll på skjermen og derved sette DevRef tracking på denne.

 

 

Jeg trenger kode for initiellt å fylle cboInterface og cboLocation med "group by" eller Distinct" for disse.

Det øverste valget settes som "--- All ---"

 

Og deretter kode som kjører på SelectedIndexChanged til å filtrere hva som vises i de andre.

 

Dette må jo passe perfekt for LINQ ?

 

Endret av Fermate
Lenke til kommentar

Ø men det var jo enkelt :

 

                Dim lInterfaces = From Endev In AllDevs
                                  Order By Endev.Interf
                                  Select Endev.Interf
                                  Distinct


                For Each s As String In lInterfaces
                    frmMain.cboInterface.Items.Add(s)
                Next

Noen ganger holder det med å spørre for å klarne hjernen :)

 

Og ingen komentarer om min Hungarian takk ;)

Lenke til kommentar

Vel jeg foretrekker å navigere XML dokumenter med system.xml.xmldocument og synes objekter er enklere enn en stream men hver sin smak.

Joda, det gjør jeg når jeg trenger å faktisk manipulere XML-filen, eller den skal leses/skrives til en klasse. Men det er jo uinteressant her. Jeg skal ikke tolke XML'en, jeg skal bare erstatte et tall med et annet i en tekstfil. ;)

 

 

Igjen: Linq to the rescue! :D

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...