I have a Russound CAA6.6 whole house audio controller (2 in fact) connected to an
[1]] alarm panel. In order to activate the audio features I had to give names to these insanely high unit numbers (400+). With a keypad, the only thing you can do is keep pressing down until you get there. I'm not about to go out like that, so I used their SDK to write a program to upload/download names from an HAI controller. Here it is in its entirety: (this is for home remember, so don't judge me on naming, commenting, or abstraction)
using System;
using System.Collections.Generic;
using System.Text;
using HAI_Shared;
using System.Threading;
namespace HAINameSetup
{
class Program
{
private class NameInfo
{
public enuNameType NameType;
public string Name;
public ushort Index;
public NameInfo(string s)
{
string[] info = s.Split(new char[] { ',' }, 3);
NameType = (enuNameType)System.Enum.Parse(typeof(enuNameType), info[0], true);
Index = ushort.Parse(info[1]);
Name = info[2];
}
}
/// <summary>
/// Used for writing name data to disk
/// </summary>
static StringBuilder nameData = new StringBuilder();
/// <summary>
/// Used for writing name data to the OmniLink device
/// </summary>
static List<NameInfo> names = null;
static ManualResetEvent Waiter = new ManualResetEvent(false);
static clsHAC HAC;
private static void WriteNamesWhenConnected(enuOmniLinkCommStatus CS)
{
try
{
if (CS == enuOmniLinkCommStatus.Connected)
{
clsOLMsgDownloadNames setNames = new clsOLMsgDownloadNames(HAC.Connection);
names.Insert(0, new NameInfo("Unit,0,None"));
HAC.Connection.Send(setNames, new HandleReceivedPacketDelegate(SetName));
}
}
catch (Exception ex)
{
Waiter.Set();
}
}
private static void ReadNamesWhenConnected(enuOmniLinkCommStatus CS)
{
try
{
if (CS == enuOmniLinkCommStatus.Connected)
{
clsOLMsgUploadNames getNames = new clsOLMsgUploadNames(HAC.Connection);
HAC.Connection.Send(getNames, new HandleReceivedPacketDelegate(HandleName));
}
}
catch (Exception ex)
{
Waiter.Set();
}
}
static void AllDone(clsOmniLinkMessageQueueItem item, byte[] msg, bool timeout)
{
// Quit the app
Waiter.Set();
}
static void SetName(clsOmniLinkMessageQueueItem item, byte[] msg, bool timeout)
{
if (!timeout)
{
// Done processing this one
if (names.Count == 0)
{
HAC.Connection.Send(new clsOLMsgEOD(HAC.Connection), new HandleReceivedPacketDelegate(AllDone));
return; // I don't know how this happens, but it does.
}
names.RemoveAt(0);
}
// Else try the last one again
if (names.Count == 0)
{
HAC.Connection.Send(new clsOLMsgEOD(HAC.Connection), new HandleReceivedPacketDelegate(AllDone));
return;
}
NameInfo ni = names[0];
clsOLMsgNameData ndMsg = new clsOLMsgNameData(HAC.Connection, ni.NameType, ni.Index, ni.Name, HAC.GetNameTypeLen());
HAC.Connection.Send(ndMsg, new HandleReceivedPacketDelegate(SetName));
}
static void HandleName(clsOmniLinkMessageQueueItem item, byte[] msg, bool timeout)
{
if (timeout)
{
HAC.Connection.Send(new clsOLMsgNAK(HAC.Connection), new HandleReceivedPacketDelegate(HandleName));
return;
}
clsOLMsgAcknowledge ack = new clsOLMsgAcknowledge(HAC.Connection);
if (clsOLMsgEOD.GetMsgType(msg) == enuOmniLinkMessageType.EOD)
{
Waiter.Set();
}
else
{
clsOLMsgNameData nd = new clsOLMsgNameData(HAC.Connection, msg, HAC.GetNameTypeLen());
nameData.AppendFormat("{0},{1},{2}\n", nd.NameType, nd.NameNumber, nd.Name);
HAC.Connection.Send(ack, new HandleReceivedPacketDelegate(HandleName));
}
}
static void Main(string[] args)
{
HAC = new HAI_Shared.clsHAC();
HAC.Connection.ControllerKey = clsUtil.HexString2ByteArray("<your HAI Key here>".ToUpper());
HAC.Connection.NetworkAddress = "<your HAI IP Address>";
HAC.Connection.NetworkPort = 4369;
HAC.PreferredNetworkProtocol = HAI_Shared.clsHAC.enuPreferredNetworkProtocol.UDP;
HAC.Connection.ConnectionType = enuOmniLinkConnectionType.Network_UDP;
if (args.Length != 2)
{
Console.WriteLine("Usage:\n HAINameSetup [read|write] <filename>");
}
else if (args[0] == "read")
{
HAC.Connection.Connect(ReadNamesWhenConnected);
Waiter.WaitOne();
System.IO.File.WriteAllText(args[1], nameData.ToString());
HAC.Connection.Disconnect();
}
else if (args[0] == "write")
{
string[] lines = System.IO.File.ReadAllLines(args[1]);
names = new List<NameInfo>();
foreach (string l in lines)
{
names.Add(new NameInfo(l));
}
HAC.Connection.Connect(WriteNamesWhenConnected);
Waiter.WaitOne();
HAC.Connection.Disconnect();
}
}
}
}
So basically you run:
HAINameSetup.exe read HAINames.txt
Then you edit it with a text editor to add, modify, or delete names, and run
HAINameSetup.exe write HAINames.txt