Hi Again,
Thought I would add my visonic version of performModuleUpdate as an example
public TsList<Module> performModuleUpdate(TsList<Module> currentList)
{
foreach( string key in controller.ModulesStatus.Keys )
{
SensorState sensor = controller.ModulesStatus[key];
Module module = null;
try
{
module = currentList.Find(delegate(Module o)
{
return o.Domain == Domain && o.Address == sensor.identifier.ToString();
});
}
catch
{
}
// add new module
if (module == null)
{
module = new Module();
module.Domain = Domain;
if (key == stateMessage)
{
module.Name = stateMessage;
module.Address = stateMessage;
module.DeviceType = HGModule.DeviceTypes.Generic;
module.Description = "Visonic Panel Status";
}
else if (key == configMessage)
{
module.Name = configMessage;
module.Address = configMessage;
module.DeviceType = HGModule.DeviceTypes.Generic;
module.Description = "Visonic Panel Config";
ModuleParameter.ModuleParameterSet(module, "ipaddress", _tcpaddress);
ModuleParameter.ModuleParameterSet(module, "port", ""+_tcpport);
}
else
{
module.Address = sensor.identifier.ToString();
module.DeviceType = Module.DeviceTypes.Sensor;
module.Description = "Visonic Panel Sensor";
}
currentList.Add(module);
}
if (module != null)
{
if (key != stateMessage && key != configMessage)
{
module.Name = sensor.Name;
module.Description = sensor.message;
ModuleParameter.ModuleParameterSet(module, "Active", "" + sensor.active);
ModuleParameter.ModuleParameterSet(module, "BatteryLow", "" + sensor.batteryLow);
ModuleParameter.ModuleParameterSet(module, "Bypassed", "" + sensor.bypassed);
//ModuleParameter.ModuleParameterSet(module, "identifier", "" + sensor.identifier);
ModuleParameter.ModuleParameterSet(module, "Message", "" + sensor.message);
ModuleParameter.ModuleParameterSet(module, "Tamper", "" + sensor.tamper);
ModuleParameter.ModuleParameterSet(module, "Tripped", "" + sensor.tripped);
ModuleParameter.ModuleParameterSet(module, "ZoneName", sensor.zoneName);
ModuleParameter.ModuleParameterSet(module, "ZoneType", sensor.zoneType);
}
}
}
return currentList;
}
Where the code refers to controller and sensors, they are internal to my code.
I noticed on your last set of release notes that you plan on changing TsList anyway.
In HomeGenieService.cs I have incorporated the following code across a few places where modules seem to get updated. An example for which is in modules_RefreshAll():
foreach (MIGServiceConfiguration.Interface iface in systemConfiguration.MIGService.Interfaces)
{
modules_RefreshGeneric(iface.Domain);
}
The code for modules_RefreshGeneric is here
internal void modules_RefreshGeneric(string domain)
{
try
{
if (systemConfiguration.GetInterface(domain).IsEnabled)
{
MIGInterface mif = GetInterface(domain);
if (mif != null)
{
systemModules = mif.performModuleUpdate(systemModules);
}
}
else
{
systemModules.RemoveAll(m => m.Domain == domain && m.RoutingNode == "");
}
}
catch (Exception ex)
{
HomeGenieService.LogEvent(Domains.HomeAutomation_HomeGenie, "modules_RefreshGeneric(" + domain + ")", ex.Message, "Exception.StackTrace", ex.StackTrace);
}
}
The code in HomeGenieService.cs for requestModuleUpdate is here:
private void requestModuleUpdate(bool v)
{
modules_RefreshAll();
modules_Sort();
}
In LoadSystemConfig() i have "attached" the event
foreach (var iface in systemConfiguration.MIGService.Interfaces)
{
var migInterface = GetInterface(iface.Domain);
// add event handler (when the interface requests a module update)
try {
if (migInterface != null)
{
migInterface.requestModuleUpdate += requestModuleUpdate;
//Thread.Sleep(1000);
migInterface.Configure(systemConfiguration);
bool isConnected = migInterface.IsConnected;
if (iface.IsEnabled && !isConnected)
{
migInterface.Connect();
}
}
}
catch { }
}
I have also rewritten modules_Sort() to be generic:
internal void modules_Sort()
{
// sort modules properties by name
foreach (var module in systemModules)
{
// various normalization stuff
module.Properties.Sort((ModuleParameter p1, ModuleParameter p2) =>
{
return p1.Name.CompareTo(p2.Name);
});
}
//
// sort modules
//
systemModules.Sort((HGModule m1, HGModule m2) =>
{
try
{
string l1 = "";
int n1 = 0;
int m1_index = m1.Address.IndexOfAny(new char[] { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' });
int m2_index = m2.Address.IndexOfAny(new char[] { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' });
if (m1_index >= 1)
{
l1 = m1.Address.Substring(0, m1_index);
int.TryParse(m1.Address.Substring(m1_index), out n1);
}
else
{
int.TryParse(m1.Address, out n1);
}
string l2 = "";
int n2 = 0;
if (m2_index >= 1)
{
l2 = m2.Address.Substring(0, m2_index);
int.TryParse(m2.Address.Substring(m2_index), out n2);
}
else
{
int.TryParse(m2.Address, out n2);
}
string d1 = m1.Domain;
if (d1.StartsWith("EmbeddedSystems."))
{
d1 = "z|" + d1;
}
string d2 = m2.Domain;
if (d2.StartsWith("EmbeddedSystems."))
{
d2 = "z|" + d2;
}
return ((d1 + "|" + l1 + n1.ToString("00000")).CompareTo(d2 + "|" + l2 + n2.ToString("00000")));
}
catch (Exception ex)
{
Console.WriteLine("Caught Sort Exception :" + ex.Message);
}
return 0;
});
}
Purely for interest, this is how I load in an external DDL as a plugin. The following goes in LoadSystemConfig().
foreach (MIGServiceConfiguration.Interface iface in systemConfiguration.MIGService.Interfaces)
{
var migInterface = GetInterface(iface.Domain);
if (migInterface == null)
{
string val = iface.findOption("Plugin");
if (val.Length > 0)
{
migService.AddPluginInterface(iface.Domain, val);
}
else
{
migService.AddInterface(iface.Domain);
}
}
}
AddPluginInterface is
public MIGInterface AddPluginInterface(string domain, string path)
{
Assembly MyDLL = Assembly.LoadFrom(path); // DLL name of assembly
Type[] types = MyDLL.GetTypes();
// Loop through the types in the assembly until we find a class that implements MIGInterface.
foreach (Type type in types)
{
if (type.GetInterface("MIGInterface") != null)
{
return createMIGInterface(domain, type);
}
}
return null;
}
And createMIGInterface is
private MIGInterface createMIGInterface(string domain, Type type)
{
// add it to the list of interfaces
MIGInterface migInterface = (MIGInterface)Activator.CreateInstance(type);
Interfaces.Add(domain, migInterface);
migInterface.InterfacePropertyChangedAction += new Action<InterfacePropertyChangedAction>(MigService_InterfacePropertyChanged);
//TODO: implement eventually a RemoveInterface method containing code:
// mif.InterfacePropertyChangedAction -= MIGService_InterfacePropertyChangedAction;
return migInterface;
}
That's all for now.....