Announcement

Collapse
No announcement yet.

TCP/IP control of HomeSeer HS3

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • TCP/IP control of HomeSeer HS3

    FINALLY got around to porting this to HS3.

    Allows setting devices, calling event using a TCP/IP XML fragment -

    <Request VR="Kitchen Toaster on please"/>
    <Request VR="Oi rat-face turn on the Kitchen Toaster now"/>
    <Request VR="Run the event Hello Word"/>
    etc.

    The VR is quite flexible, it looks for devices and events explicitly and works out the operation allowed itself, if you want the status just send the VR without an operation -
    <Request VR="Kitchen toaster"/>


    The easiest way to test it is using Telnet -

    Telnet <computer> 6582

    You'll get back a bunch of lines which tell you what it knows about your system.

    <Request VR="Quit"/> quits the connection fairly evidently.


    Extract, down in HSPI_ActionRequest\obj\x86\Release\, copy the HSPI_ActionRequest.exe into your HS3 directory and enable it.
    Full source code included.


    I use this to control HS from my Android mobile and from MediaPortal too.

    Scheduling (in 5 minutes, after 20 seconds etc.) doesn't work yet placeholders only.

    New version with (my ScriptDevice) changes.
    Attached Files
    Last edited by JamesWestoby; December 30th, 2014, 10:43 AM. Reason: New version

  • #2
    Hi James:

    Trying this out from command line. Cool. Could you explain the syntax? I'm assuming 'VR' represents voice recognition, so do you have to have a device VR property checked for this to work? Also, again from command line, I can turn off or on a light, but have to stop and restart the session for more than one command, or am I missing something obvious?

    Thanks for sharing this.
    Don

    Comment


    • #3
      New and usage

      Sorry Don (nice to hear from you).

      VR doesn't have to be set up (I did for the last version but for HS3....).

      For events it uses the event name, so that is a word(s) match in any VR you care to send it.

      So if you have an event called 'Foo bah' it looks in the supplied VR for '....... foo bah .......'


      For devices it is a bit cleverer, it will take parts of the device and look for them (and now will remember your last location).

      So if you have a device called 'foo' in the 'bah' location it will look for any combination like -

      'Please turn the foo in the bah off' or 'turn the bah foo off' or even 'bah foo off'

      That is assuming that a foo can be on or off...... It is cleverer than that and actually looks at the operations permitted, so if a foo opens and closes 'open the stuffing foo in the bah please' will do <grin>.

      If you ask the 'bah foo' only, with no recognised operation then you get the status back instead. So -

      'What is the Bah Foo'

      Sends back Open (or whatever). Really should strip a question mark though, should I!


      I use this with an 'in script' property and a separate _Interface script (below) that makes controlling things nice and tight.


      In the room script -

      Dim m As String = _Device("House Mode")

      _Device(myLocation & " Lights") = "Off"



      #Region "Interface methods"
      Private Property _Device(ByVal Name As String) As String
      Get
      Return CType(hs.RunScriptFunc("_Interface.vb", "_Device", Name, True, False), String)
      End Get
      Set(ByVal Value As String)
      hs.RunScriptFunc("_Interface.vb", "_Device", Name & "=" & Value, True, False)
      End Set
      End Property

      Private Function _Event(ByRef Name As String, Optional ByRef VR As String = "") As String
      Return CType(hs.RunScriptFunc("_Interface.vb", "_Event", Name & "=" & VR, True, False), String)
      End Function

      Private Function _Phrase(ByVal Name As String, ByVal Codes As String) As String
      Return CType(hs.RunScriptFunc("_Interface.vb", "_Phrase", Name & "|" & Codes, True, False), String)
      End Function
      #End Region



      And the separate _Interface script -

      Private Const myScript As String = "_Interface.vb"

      Public Function _Device(ByRef Line As String) As String
      Dim v() As String = Split(Line, "="c)
      If (UBound(v) = 0) Then
      Dim dv As Integer = hs.GetDeviceRefByName(v(0))
      Dim s As String = Trim(hs.DeviceString(dv))
      Return Iif(s = "", "" & hs.DeviceValue(dv), s)
      Else
      Dim dv As Integer = hs.GetDeviceRefByName(v(0))
      'hs.WriteLog("_Device", v(0) & " " & v(1))
      If (dv.Interface = "ScriptDevice") Then
      hs.SetDeviceString(dv, v(1), True)
      Else
      hs.SetDeviceValueByRef(dv, CDbl(TextToValue(v(1)), True)
      End If
      Return ""
      End If
      End Function

      Public Function _Event(ByRef Line As String) As String
      Dim r As Integer
      Dim v() As String = Split(Line, "="c)
      If (UBound(v) = 0) Then
      r = hs.TriggerEvent(v(0))
      Else
      r = hs.TriggerEventEx(1, v(0), v(1))
      End If
      Return IIf(r = 0, "", "Error!")
      End Function

      Public Function _Phrase(ByRef Values() As String) As String
      Get
      'return a conversational string from the phrase name
      'first value is a shorthand description which gets string template section
      'subsequent values are string id=value lines, where ids are replaced by the values
      Dim Items() As String = hs.GetINISectionEx(Values(0,0), "Phrase.Cfg")
      If (Items Is Nothing) Then Return Name & " Undefined"
      Dim c As Integer = Items.Length
      If (c = 0) Then Return Line
      Randomize()
      Dim x As integer = Int(c * Rnd())
      Dim t As String = Items(x)
      Dim k() As String = t.Split("="c)
      t = k(1)
      Dim i as Integer
      For i = Ubound(Codes) To 1 Step -1
      k = Codes(i).Split("="c)
      t = t.Replace("<" & k(0) & ">", k(1))
      Next i
      Return t
      End Get
      End Function

      #Region "Private methods"
      Private Function TextToValue(ByVal DevRef As Integer, ByRef Value As String) As String
      'special processing for an "any string" device
      Dim d As Scheduler.Classes.DeviceClass = CType(hs.GetDeviceByRef(DevRef), Scheduler.Classes.DeviceClass)
      If (d.Device_Type_String(hs) = "String") Then Return "1"
      'Log("TextToValue : " & Value, LogLevel.Debug)
      Dim v As String = UCase(Value)
      Dim vpl As HomeSeerAPI.VSVGPairs.VSPair() = hs.DeviceVSP_GetAllStatus(DevRef)
      For Each vp As VSPair In vpl 'check the text against the possible single/range values
      If (vp.PairType = VSVGPairType.Range) Then
      'hs.WriteLog("Range", "" & vp.RangeStart & " " & vp.RangeEnd)
      Dim vt As String = v 'remove the prefix and suffix text
      Dim p As String
      p = UCase(vp.RangeStatusPrefix)
      If (vt.StartsWith(p)) Then vt = vt.Substring(p.Length)
      p = UCase(vp.RangeStatusSuffix)
      If (vt.EndsWith(p)) Then vt = vt.Substring(0, (vt.Length - p.Length))
      vt = vt.Trim()
      If (IsNumeric(vt)) Then 'left with a number?
      Dim fv As Double = CDbl(vt)
      If ((vp.RangeStart <= fv) And (fv <= vp.RangeEnd)) Then Return "" & fv
      End If
      Else 'VSVGPairType.SingleValue
      'hs.WriteLog("Single", "" & vp.Value)
      Dim fv As Double = vp.Value
      Dim spv As String = UCase(ValueToText(DevRef, fv))
      If (v = spv) Then Return "" & fv
      End If
      Next
      Return "" 'failed, return empty string
      End Function

      Private Function ValueToText(ByVal DevRef As Integer, ByRef Value As Double) As String
      Return hs.DeviceVSP_GetStatus(DevRef, Value, ePairStatusControl.Status)
      End Function
      #End Region
      Last edited by JamesWestoby; December 30th, 2014, 10:47 AM. Reason: Typo

      Comment


      • #4
        Script Device

        Just about to update this too.....

        http://board.homeseer.com/showthread.php?t=169785

        Comment


        • #5
          Shouldn't lose connection

          Here's a run (with my typos) from Telnet/command line -
          (Abbreviated the devices/Events returned though.)

          Started with -
          Telnet Selenium 6582



          <Device Location="Ground Family" Name="Motion" Operations="No Motion|0-255"/>
          <Device Location="First Bath" Name="Radio" Operations=""/>
          <Device Location="Ground Bath" Name="Clock" Operations="Dim|Bright"/>
          <Device Location="Ground Bath" Name="Radio" Operations=""/>

          <Device Location="First Bed 3" Name="Lights" Operations="Off|On|0-99"/>
          <Device Location="First Bed 3" Name="Radio" Operations=""/>
          <Device Location="First Bed 1" Name="CCTV" Operations="Off|On|Stop|Record"/>
          <Device Location="First Bath" Name="Clock" Operations="Dim|Bright"/>
          <Event Group="Time" Name="WEA22 Tick"/>
          <Event Group="Motion" Name="Path Motion"/>
          <Event Group="Motion" Name="Drive Motion"/>

          <Event Group="Time" Name="Sunset"/>
          <Event Group="Motion" Name="Family Motion"/>
          <Response Status="No VR element defined!"/>
          <Request VR="Ground Hall Lights on"/>
          <Response Status="Unknown/Ambiguous!"/>
          <Request vr="Garden Path Lights On"/>
          <Response Status=""/>
          <Request VR="Garden Path Lights to on"/>
          <Response Status=""/>
          <Request VR="Garden Path Lights status"/>
          <Response Status="On"/>
          <Request VE
          <Response Status="No VR element defined!"/>
          <Request VR="Quit"/>

          Connection to host lost.
          C:\Users\James>

          So doesn't lose the connection (although the first line using Telnet comes out blank, so I just hit return).

          Comment


          • #6
            Thanks for the suggestions.
            Don

            Comment

            Working...
            X