Announcement

Collapse
No announcement yet.

IR control (No plugin required)

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

    IR control (No plugin required)

    OK, so while I was quite willing to pay over money for the HS3 GC plugin, it didin't provide what I wanted - a way to send IR from a script.
    (ALL Event) Scripts use a simple way of setting devices values using strings (see whinge later) -
    _Device("Family Room Lights") = "On"
    (Get the value using x = _Device("Family Room Lights")
    Note they are strings - no technology specific 'magic numbers' here!

    BACKGROUND
    I wrote a plugin (HSPI_ScriptDevice) which calls a script for a device.
    This insulates the operation to the device from the underlying technology,
    even abstract/status devices like House Occupancy!
    So I dim a light using 0-100%, not 0-32 for LightwaveRF etc. it abstracts the technology from the operation.
    ALL my devices with the exception of Z-Wave (darn it!) are 'ScriptDevices'
    Now I couldn't find callable GlobalCache function(s) in the HS plugin.
    Also once the code is in HS I can't tweak it (to change the repeat).
    Final 'nail in the coffin'? I don't think it shows up on the device management/status pages.

    So I wrote my own, simple (IR blaster only) ScriptDevice.
    (GlobalCache provide a VERY useful ,easily found, API - except for [6] below!)

    Here it is (numbers in '[]' are for reference) -
    ==============
    Imports System.Net.Sockets
    Imports System.Threading
    Imports Scheduler.Classes

    'Module _GlobalCache
    Private Const myScript As String = "_GlobalCache.vb"
    Private Const IRTimeout As Integer = 200
    [0] Public Function IR(ByRef Parms() As Object) As String
    Dim r As String = ""
    Dim d As Integer = CType(Parms(0), Integer)
    Dim n As String = CType(Parms(2), String)
    Dim q As DeviceClass = CType(hs.GetDeviceByRef(d), DeviceClass)
    'Dim q As Object = hs.GetDeviceByRef(d)
    [1] Dim a As String = q.Address(hs) 'Config file
    [2] Dim s As String = q.Location2(hs) & " " & q.Location(hs) & " " & q.Name(hs)
    s = s.Replace(" ", " ")
    s = s.Trim()
    hs.WriteLog(myScript, s & " press " & n)
    Dim k() As String = n.Split(","c)
    For i As Integer = 0 To UBound(k)
    k(i) = hs.GetINISetting(s, k(i), "", a)
    hs.WriteLog("", "For " & k(i))
    Next i
    'read IP and IR from INI or default
    [3] Dim ip As String = hs.GetINISetting("General", "IP", "192.168.1.209", a)
    Try
    Dim st As New SenderIR(ip, k)
    Dim t As Thread = New Thread(AddressOf st.SendIR)
    t.Start()
    If (t.Join(IRTimeout * UBound(k))) Then r = st.myResult Else r = "IR Error!)"
    Catch ex As Exception
    hs.WriteLog(myScript, "" & ex.ToString)
    r = "IR Exception!"
    End Try
    'never return what was supplied, or couldn't repeat it
    [4] Return r
    End Function
    #Region "Private IR class"
    [5] Private Class SenderIR
    Private Const IRPort As Integer = 4998
    Private myIP As String
    Private myIRs() As String
    Public myResult As String
    'constructors/destructor
    Public Sub New(ByRef IP As String, ByRef IRs() As String)
    myIP = IP
    myIRs = IRs
    myResult = ""
    End Sub
    'public (thread) method
    Public Sub SendIR()
    Dim c As TcpClient = Nothing
    Dim s As NetworkStream = Nothing
    Dim w As System.IO.StreamWriter = Nothing
    Dim r As System.IO.StreamReader = Nothing
    Dim t As String = ""
    Try
    c = New TcpClient(myIP, IRPort)
    s = c.GetStream()
    w = New System.IO.StreamWriter(s)
    r = New System.IO.StreamReader(s)
    For i As Integer = 0 To UBound(myIRs)
    If (myIRs(I) <> "") Then
    w.WriteLine(myIRs(i) & vbCr)
    w.Flush()
    [6] 'fibs, doesn't send back a line with a CR on the end!
    Dim b(64) As Char
    Dim rx As Integer = r.Read(b, 0, 64)
    t = New String(b)
    If (t.Contains("ERR")) Then myResult = "IR Fail!"
    'Thread.Sleep(1000)
    End If
    Next i
    Catch ex As Exception
    'hs.WriteLog(" ", "Send " & ex.ToString())
    myResult = "IR Exceptioon"
    End Try
    If (Not (r Is Nothing)) Then r.Close()
    If (Not (w Is Nothing)) Then w.Close()
    If (Not (s Is Nothing)) Then s.Close()
    If (Not (c Is Nothing)) Then c.Close()
    End Sub
    End Class
    #End Region
    'End Module
    ===============

    IR [0] is the function called by the HSPI_ScriptDevice, standard HS parameters.
    Internal class [5] sends to the GC (and can be ignored).
    it uses a simple Ini file, [1] passed to the device by HS/HSPI_ScriptDevice.
    As you can see, my GC is at 192.168.1.209 [3], but it will find the -
    [General]
    IP=xxxxxx
    line in the Ini.

    Device section in the Ini, full name [2], looks like -
    [Ground Family Room Plasma]
    On=sendir,1:3,4444,34500,8,1,34,48,24,12,24,960
    Off=sendir,1:3,4444,34500,1,1,34,48,24,12,24,960
    Mute=sendir,1:3,4444,34500,1,1,34,48,24,12,24,960
    Easy to edit/change
    the 4444 is just a ref number, anything is fine if not overlapping requests
    the :3 is the blaster
    the number after the 34500 is the repeat - plasma wants a repeated ON
    Can put buttons onto the device managment screen which also show on the device status screen.
    (Status reporting is a bit redundant as even if the GC received and sent the IR who is to say the cat isn't sitting in front of the blaster?)

    CAVEAT
    If you're NOT using my HSPI_ScriptDevice (and who is?) then it isn't directly usable.
    But as you can see, send the class [5] the 'sendir...' strings and off it goes.
    The device is set up as an 'AnyString' [4] - so the value can be sent repeatedly if you wish.
    (Aside whinge - HS seems not to like calling the plugin HSEvent if the value is set to the same value - why not!)

    Thoughts, bouquets or brickbats - PM or better [rarely log on nowadays, too much to do] email me HomeSeerRemote 'at' athame.net.
    (That's A simple Android VR app I wrote to drive HomeSeer, it's on the Play store.)
Working...
X