I've seen a number of posts from people who want to send YAC CallerID info from HomeSeer. I use YAC listeners for stuff myself and I created a HomeSeer 2 .NET script to send out CallerID info or other messages to YAC listeners *WITHOUT* having to install the YAC server or the YacSendText program. I just thought it was overkill to have extra processes running all the time (and executing a complete shell session) just to send a few bytes of information out when there was a call coming in.
So here is the function I use in a number of places (including my CallerID script) to send out info to YAC listeners. It is a .NET script (.vb) function that can be placed in its own file or used along with other scripts (ZIP file also attached to message to retain formatting)
It is simple to use...
YacSendText("listener1,listener2,listener3", "", "111-111-1111", "Jane Doe")
to send a CallerID notification or
YacSendText("listener1,listener2,listener3", "I Have Something To Say")
Will transmit a YAC general message.
The first parameter is a list of YAC listeners to transmit to, separated with a comma. IP addresses or resolvable host names will work.
' Transmit a YAC message to the YAC listeners in ClientList. Message is a non-CID message to transmit, CIDNumber is the phone number and CIDName
' is the caller name. Message is ignored if CIDName or CIDNumber are present.
Sub YacSendText(ByVal ClientList As String, ByVal Message As String, Optional ByVal CIDNumber As String = "", Optional ByVal CIDName As String = "")
Dim tcpClient As System.Net.Sockets.TcpClient
Dim Client() As String
Dim ClientNum As Integer
' Name or number override message
If CIDName.Length() > 0 Or CIDNumber.Length() > 0 Then
Message = "@CALL" & Trim(CIDName) & "~" & Trim(CIDNumber)
End If
'Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes(Message) ' Encode string type to byte
' HomeSeer does not expose the Encoding .NET class that we need, so we have to do the work ourselves
Dim MsgLen as Integer = Len(Message)
Dim SendBytes(MsgLen) as Byte
Dim Ch as Integer
For Ch = 0 to MsgLen - 1
SendBytes(Ch) = Asc(Mid(Message,Ch + 1, 1))
Next
SendBytes(MsgLen) = 0
MsgLen = MsgLen + 1
Client = Split(ClientList, ",") ' Get the list of clients
For ClientNum = 0 To UBound(Client) ' Transmit to each client in the list
Try
tcpClient = New System.Net.Sockets.TcpClient
tcpClient.SendTimeout() = 1000 ' Quick abort
tcpClient.NoDelay = True ' Short burst of info
tcpClient.Connect(Client(ClientNum), 10629) ' Standard YAC port 10629
Dim networkStream As Net.Sockets.NetworkStream = tcpClient.GetStream()
If networkStream.CanWrite Then ' Assure write access
hs.writelog("YACSendText", "Yac Send To: " & Client(ClientNum) & " - " & Message)
networkStream.Write(sendBytes, 0, MsgLen) ' Ship it out
End If
tcpClient.Close() ' Immediate termination
Catch Ex As Exception
' Ex.ToString will contain the error message if a transmit fails. Computers
' in the send list that are offline will fail, so failures are not uncommon.
' hs.writelog("YACSendText", "Yac Error: " & Ex.ToString)
End Try
Next
End Sub
So here is the function I use in a number of places (including my CallerID script) to send out info to YAC listeners. It is a .NET script (.vb) function that can be placed in its own file or used along with other scripts (ZIP file also attached to message to retain formatting)
It is simple to use...
YacSendText("listener1,listener2,listener3", "", "111-111-1111", "Jane Doe")
to send a CallerID notification or
YacSendText("listener1,listener2,listener3", "I Have Something To Say")
Will transmit a YAC general message.
The first parameter is a list of YAC listeners to transmit to, separated with a comma. IP addresses or resolvable host names will work.
' Transmit a YAC message to the YAC listeners in ClientList. Message is a non-CID message to transmit, CIDNumber is the phone number and CIDName
' is the caller name. Message is ignored if CIDName or CIDNumber are present.
Sub YacSendText(ByVal ClientList As String, ByVal Message As String, Optional ByVal CIDNumber As String = "", Optional ByVal CIDName As String = "")
Dim tcpClient As System.Net.Sockets.TcpClient
Dim Client() As String
Dim ClientNum As Integer
' Name or number override message
If CIDName.Length() > 0 Or CIDNumber.Length() > 0 Then
Message = "@CALL" & Trim(CIDName) & "~" & Trim(CIDNumber)
End If
'Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes(Message) ' Encode string type to byte
' HomeSeer does not expose the Encoding .NET class that we need, so we have to do the work ourselves
Dim MsgLen as Integer = Len(Message)
Dim SendBytes(MsgLen) as Byte
Dim Ch as Integer
For Ch = 0 to MsgLen - 1
SendBytes(Ch) = Asc(Mid(Message,Ch + 1, 1))
Next
SendBytes(MsgLen) = 0
MsgLen = MsgLen + 1
Client = Split(ClientList, ",") ' Get the list of clients
For ClientNum = 0 To UBound(Client) ' Transmit to each client in the list
Try
tcpClient = New System.Net.Sockets.TcpClient
tcpClient.SendTimeout() = 1000 ' Quick abort
tcpClient.NoDelay = True ' Short burst of info
tcpClient.Connect(Client(ClientNum), 10629) ' Standard YAC port 10629
Dim networkStream As Net.Sockets.NetworkStream = tcpClient.GetStream()
If networkStream.CanWrite Then ' Assure write access
hs.writelog("YACSendText", "Yac Send To: " & Client(ClientNum) & " - " & Message)
networkStream.Write(sendBytes, 0, MsgLen) ' Ship it out
End If
tcpClient.Close() ' Immediate termination
Catch Ex As Exception
' Ex.ToString will contain the error message if a transmit fails. Computers
' in the send list that are offline will fail, so failures are not uncommon.
' hs.writelog("YACSendText", "Yac Error: " & Ex.ToString)
End Try
Next
End Sub
Comment