mirror of
https://github.com/excaliburpartners/OmniLinkBridge
synced 2024-12-22 10:42:24 +00:00
1.1.8 - Fix MQTT undefined settings and add unit tests
This commit is contained in:
parent
a5e9fae32e
commit
7d87416915
|
@ -1,6 +1,7 @@
|
|||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Mail;
|
||||
using System.Reflection;
|
||||
|
||||
namespace OmniLinkBridge
|
||||
{
|
||||
|
@ -75,5 +76,10 @@ namespace OmniLinkBridge
|
|||
// Pushover Notifications
|
||||
public static string pushover_token;
|
||||
public static string[] pushover_user;
|
||||
|
||||
public static object GetValue(string propName)
|
||||
{
|
||||
return typeof(Global).GetField(propName, BindingFlags.Public | BindingFlags.Static).GetValue(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace OmniLinkBridge
|
|||
|
||||
try
|
||||
{
|
||||
Settings.LoadSettings();
|
||||
Settings.LoadSettings(Global.config_file);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
|
@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
|||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.1.7.0")]
|
||||
[assembly: AssemblyFileVersion("1.1.7.0")]
|
||||
[assembly: AssemblyVersion("1.1.8.0")]
|
||||
[assembly: AssemblyFileVersion("1.1.8.0")]
|
||||
|
|
|
@ -16,10 +16,18 @@ namespace OmniLinkBridge
|
|||
public static bool ShowDebug { get; set; }
|
||||
public static bool UseEnvironment { get; set; }
|
||||
|
||||
public static void LoadSettings()
|
||||
public static void LoadSettings(string file)
|
||||
{
|
||||
NameValueCollection settings = LoadCollection(Global.config_file);
|
||||
LoadSettings(LoadCollection(file));
|
||||
}
|
||||
|
||||
public static void LoadSettings(string[] lines)
|
||||
{
|
||||
LoadSettings(LoadCollection(lines));
|
||||
}
|
||||
|
||||
public static void LoadSettings(NameValueCollection settings)
|
||||
{
|
||||
// HAI / Leviton Omni Controller
|
||||
Global.controller_address = settings.ValidateHasValue("controller_address");
|
||||
Global.controller_port = settings.ValidatePort("controller_port");
|
||||
|
@ -122,10 +130,12 @@ namespace OmniLinkBridge
|
|||
{
|
||||
ConcurrentDictionary<int, T> ret = new ConcurrentDictionary<int, T>();
|
||||
|
||||
if (settings.CheckEnv(section) == null)
|
||||
string value = settings.CheckEnv(section);
|
||||
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return ret;
|
||||
|
||||
string[] ids = settings.CheckEnv(section).Split(',');
|
||||
string[] ids = value.Split(',');
|
||||
|
||||
for (int i = 0; i < ids.Length; i++)
|
||||
{
|
||||
|
@ -195,6 +205,11 @@ namespace OmniLinkBridge
|
|||
{
|
||||
try
|
||||
{
|
||||
string value = settings.CheckEnv(section);
|
||||
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return new HashSet<int>();
|
||||
|
||||
return new HashSet<int>(settings.CheckEnv(section).ParseRanges());
|
||||
}
|
||||
catch
|
||||
|
@ -241,7 +256,7 @@ namespace OmniLinkBridge
|
|||
{
|
||||
string value = settings.CheckEnv(section);
|
||||
|
||||
if (value == null)
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return new MailAddress[] {};
|
||||
|
||||
string[] emails = value.Split(',');
|
||||
|
@ -292,55 +307,49 @@ namespace OmniLinkBridge
|
|||
}
|
||||
}
|
||||
|
||||
private static NameValueCollection LoadCollection(string sFile)
|
||||
private static NameValueCollection LoadCollection(string[] lines)
|
||||
{
|
||||
NameValueCollection settings = new NameValueCollection();
|
||||
|
||||
foreach(string line in lines)
|
||||
{
|
||||
if (line.StartsWith("#"))
|
||||
continue;
|
||||
|
||||
int pos = line.IndexOf('=', 0);
|
||||
|
||||
if (pos == -1)
|
||||
continue;
|
||||
|
||||
string key = line.Substring(0, pos).Trim();
|
||||
string value = line.Substring(pos + 1).Trim();
|
||||
|
||||
settings.Add(key, value);
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
private static NameValueCollection LoadCollection(string sFile)
|
||||
{
|
||||
if (ShowDebug)
|
||||
log.Debug($"Using settings file {sFile}");
|
||||
|
||||
if(!File.Exists(sFile))
|
||||
{
|
||||
log.Warn($"Unable to locate settings file {sFile}");
|
||||
return settings;
|
||||
return new NameValueCollection();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
FileStream fs = new FileStream(sFile, FileMode.Open, FileAccess.Read);
|
||||
StreamReader sr = new StreamReader(fs);
|
||||
|
||||
while (true)
|
||||
{
|
||||
string line = sr.ReadLine();
|
||||
|
||||
if (line == null)
|
||||
break;
|
||||
|
||||
if (line.StartsWith("#"))
|
||||
continue;
|
||||
|
||||
int pos = line.IndexOf('=', 0);
|
||||
|
||||
if (pos == -1)
|
||||
continue;
|
||||
|
||||
string key = line.Substring(0, pos).Trim();
|
||||
string value = line.Substring(pos + 1).Trim();
|
||||
|
||||
settings.Add(key, value);
|
||||
}
|
||||
|
||||
sr.Close();
|
||||
fs.Close();
|
||||
return LoadCollection(File.ReadAllLines(sFile));
|
||||
}
|
||||
catch (FileNotFoundException ex)
|
||||
{
|
||||
log.Error("Error parsing settings file " + sFile, ex);
|
||||
throw;
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
using System;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OmniLinkBridge;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace OmniLinkBridgeTest
|
||||
{
|
||||
[TestClass]
|
||||
public class AssemblyTestHarness
|
||||
{
|
||||
[AssemblyInitialize]
|
||||
public static void InitializeAssembly(TestContext context)
|
||||
{
|
||||
Global.config_file = "OmniLinkBridge.ini";
|
||||
Settings.LoadSettings();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,11 +9,40 @@ namespace OmniLinkBridgeTest
|
|||
[TestClass]
|
||||
public class ExtensionTest
|
||||
{
|
||||
[TestMethod]
|
||||
public void TestToCelsius()
|
||||
{
|
||||
Assert.AreEqual(-40, ((double)-40).ToCelsius());
|
||||
Assert.AreEqual(0, ((double)32).ToCelsius());
|
||||
Assert.AreEqual(50, ((double)122).ToCelsius());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestToOmniTemp()
|
||||
{
|
||||
// -40C is 0
|
||||
double min = -40;
|
||||
Assert.AreEqual(0, min.ToOmniTemp());
|
||||
|
||||
// 87.5C is 255
|
||||
double max = 87.5;
|
||||
Assert.AreEqual(255, max.ToOmniTemp());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestIsBitSet()
|
||||
{
|
||||
Assert.AreEqual(true, ((byte)1).IsBitSet(0));
|
||||
Assert.AreEqual(false, ((byte)2).IsBitSet(0));
|
||||
Assert.AreEqual(true, ((byte)3).IsBitSet(0));
|
||||
Assert.AreEqual(true, ((byte)3).IsBitSet(1));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestParseRange()
|
||||
{
|
||||
List<int> blank = "".ParseRanges();
|
||||
Assert.AreEqual(0, blank.Count);
|
||||
List<int> empty = "".ParseRanges();
|
||||
Assert.AreEqual(0, empty.Count);
|
||||
|
||||
List<int> range = "1-3,5,6".ParseRanges();
|
||||
CollectionAssert.AreEqual(new List<int>(new int[] { 1, 2, 3, 5, 6 }), range);
|
||||
|
|
|
@ -3,6 +3,8 @@ using System.Text;
|
|||
using System.Collections.Generic;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OmniLinkBridge.Notifications;
|
||||
using OmniLinkBridge;
|
||||
using System.Net.Mail;
|
||||
|
||||
namespace OmniLinkBridgeTest
|
||||
{
|
||||
|
@ -12,6 +14,16 @@ namespace OmniLinkBridgeTest
|
|||
[TestMethod]
|
||||
public void SendNotification()
|
||||
{
|
||||
// This is an integration test
|
||||
Global.mail_server = "localhost";
|
||||
Global.mail_tls = false;
|
||||
Global.mail_port = 25;
|
||||
Global.mail_from = new MailAddress("OmniLinkBridge@localhost");
|
||||
Global.mail_to = new MailAddress[]
|
||||
{
|
||||
new MailAddress("mailbox@localhost")
|
||||
};
|
||||
|
||||
Notification.Notify("Title", "Description");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,11 +47,11 @@
|
|||
<Reference Include="System.Core" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AssemblyTestHarness.cs" />
|
||||
<Compile Include="ExtensionTest.cs" />
|
||||
<Compile Include="Mock\MockOmniLinkII.cs" />
|
||||
<Compile Include="Mock\SendCommandEventArgs.cs" />
|
||||
<Compile Include="MQTTTest.cs" />
|
||||
<Compile Include="SettingsTest.cs" />
|
||||
<Compile Include="NotificationTest.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
|
|
274
OmniLinkBridgeTest/SettingsTest.cs
Normal file
274
OmniLinkBridgeTest/SettingsTest.cs
Normal file
|
@ -0,0 +1,274 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OmniLinkBridge;
|
||||
|
||||
namespace OmniLinkBridgeTest
|
||||
{
|
||||
[TestClass]
|
||||
public class SettingsTest
|
||||
{
|
||||
private string[] RequiredSettings()
|
||||
{
|
||||
return new string[]
|
||||
{
|
||||
"controller_address = 1.1.1.1",
|
||||
"controller_port = 4369",
|
||||
"controller_key1 = 00-00-00-00-00-00-00-01",
|
||||
"controller_key2 = 00-00-00-00-00-00-00-02",
|
||||
};
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestControllerSettings()
|
||||
{
|
||||
Assert.ThrowsException<Exception>(() => Settings.LoadSettings(new string[]
|
||||
{
|
||||
"controller_address="
|
||||
}));
|
||||
|
||||
List<string> lines = new List<string>(RequiredSettings());
|
||||
lines.AddRange(new string[]
|
||||
{
|
||||
"controller_name = MyController"
|
||||
});
|
||||
Settings.LoadSettings(lines.ToArray());
|
||||
Assert.AreEqual("1.1.1.1", Global.controller_address);
|
||||
Assert.AreEqual(4369, Global.controller_port);
|
||||
Assert.AreEqual("00-00-00-00-00-00-00-01", Global.controller_key1);
|
||||
Assert.AreEqual("00-00-00-00-00-00-00-02", Global.controller_key2);
|
||||
Assert.AreEqual("MyController", Global.controller_name);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestTimeSyncSettings()
|
||||
{
|
||||
// Default should be false
|
||||
Settings.LoadSettings(RequiredSettings());
|
||||
Assert.AreEqual(false, Global.mqtt_enabled);
|
||||
|
||||
// Test minimal settings
|
||||
List<string> lines = new List<string>(RequiredSettings());
|
||||
lines.AddRange(new string[]
|
||||
{
|
||||
"time_sync = yes",
|
||||
"time_interval = 60",
|
||||
"time_drift = 10"
|
||||
});
|
||||
Settings.LoadSettings(lines.ToArray());
|
||||
Assert.AreEqual(true, Global.time_sync);
|
||||
Assert.AreEqual(60, Global.time_interval);
|
||||
Assert.AreEqual(10, Global.time_drift);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestVerboseSettings()
|
||||
{
|
||||
// Default should be false
|
||||
Settings.LoadSettings(RequiredSettings());
|
||||
Assert.AreEqual(false, Global.verbose_unhandled);
|
||||
|
||||
// Check each setting correctly sets
|
||||
foreach (string setting in new string[] {
|
||||
"verbose_unhandled",
|
||||
"verbose_event",
|
||||
"verbose_area",
|
||||
"verbose_zone",
|
||||
"verbose_thermostat_timer",
|
||||
"verbose_thermostat",
|
||||
"verbose_unit",
|
||||
"verbose_message"
|
||||
})
|
||||
{
|
||||
List<string> lines = new List<string>(RequiredSettings());
|
||||
lines.Add($"{setting} = yes");
|
||||
Settings.LoadSettings(lines.ToArray());
|
||||
Assert.AreEqual(true, Global.GetValue(setting));
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestWebAPISettings()
|
||||
{
|
||||
// Default should be false
|
||||
Settings.LoadSettings(RequiredSettings());
|
||||
Assert.AreEqual(false, Global.mqtt_enabled);
|
||||
|
||||
// Test minimal settings
|
||||
List<string> lines = new List<string>(RequiredSettings());
|
||||
lines.AddRange(new string[]
|
||||
{
|
||||
"webapi_enabled = yes",
|
||||
"webapi_port = 8000",
|
||||
"webapi_override_zone = id=20;device_type=motion"
|
||||
});
|
||||
Settings.LoadSettings(lines.ToArray());
|
||||
Assert.AreEqual(true, Global.webapi_enabled);
|
||||
Assert.AreEqual(8000, Global.webapi_port);
|
||||
|
||||
Dictionary<int, OmniLinkBridge.WebAPI.OverrideZone> override_zone = new Dictionary<int, OmniLinkBridge.WebAPI.OverrideZone>()
|
||||
{
|
||||
{ 20, new OmniLinkBridge.WebAPI.OverrideZone { device_type = OmniLinkBridge.WebAPI.DeviceType.motion }}
|
||||
};
|
||||
|
||||
Assert.AreEqual(override_zone.Count, Global.webapi_override_zone.Count);
|
||||
foreach (KeyValuePair<int, OmniLinkBridge.WebAPI.OverrideZone> pair in override_zone)
|
||||
{
|
||||
Global.webapi_override_zone.TryGetValue(pair.Key, out OmniLinkBridge.WebAPI.OverrideZone value);
|
||||
Assert.AreEqual(override_zone[pair.Key].device_type, value.device_type);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestMQTTSettings()
|
||||
{
|
||||
// Default should be false
|
||||
Settings.LoadSettings(RequiredSettings());
|
||||
Assert.AreEqual(false, Global.mqtt_enabled);
|
||||
|
||||
// Test minimal settings
|
||||
List<string> lines = new List<string>(RequiredSettings());
|
||||
lines.AddRange(new string[]
|
||||
{
|
||||
"mqtt_enabled = yes",
|
||||
"mqtt_server = localhost",
|
||||
"mqtt_port = 1883"
|
||||
});
|
||||
Settings.LoadSettings(lines.ToArray());
|
||||
Assert.AreEqual(true, Global.mqtt_enabled);
|
||||
Assert.AreEqual("localhost", Global.mqtt_server);
|
||||
Assert.AreEqual(1883, Global.mqtt_port);
|
||||
Assert.AreEqual("omnilink", Global.mqtt_prefix);
|
||||
Assert.AreEqual("homeassistant", Global.mqtt_discovery_prefix);
|
||||
Assert.AreEqual(string.Empty, Global.mqtt_discovery_name_prefix);
|
||||
|
||||
// Test additional settings
|
||||
lines.AddRange(new string[]
|
||||
{
|
||||
"mqtt_username = myuser",
|
||||
"mqtt_password = mypass",
|
||||
"mqtt_prefix = myprefix",
|
||||
"mqtt_discovery_prefix = mydiscoveryprefix",
|
||||
"mqtt_discovery_name_prefix = mynameprefix",
|
||||
"mqtt_discovery_ignore_zones = 1,2-3,4",
|
||||
"mqtt_discovery_ignore_units = 2-5,7",
|
||||
"mqtt_discovery_override_zone = id=5;device_class=garage_door",
|
||||
"mqtt_discovery_override_zone = id=7;device_class=motion",
|
||||
});
|
||||
Settings.LoadSettings(lines.ToArray());
|
||||
Assert.AreEqual("myuser", Global.mqtt_username);
|
||||
Assert.AreEqual("mypass", Global.mqtt_password);
|
||||
Assert.AreEqual("myprefix", Global.mqtt_prefix);
|
||||
Assert.AreEqual("mydiscoveryprefix", Global.mqtt_discovery_prefix);
|
||||
Assert.AreEqual("mynameprefix ", Global.mqtt_discovery_name_prefix);
|
||||
Assert.IsTrue(Global.mqtt_discovery_ignore_zones.SetEquals(new int[] { 1, 2, 3, 4 }));
|
||||
Assert.IsTrue(Global.mqtt_discovery_ignore_units.SetEquals(new int[] { 2, 3, 4, 5, 7 }));
|
||||
|
||||
Dictionary<int, OmniLinkBridge.MQTT.OverrideZone> override_zone = new Dictionary<int, OmniLinkBridge.MQTT.OverrideZone>()
|
||||
{
|
||||
{ 5, new OmniLinkBridge.MQTT.OverrideZone { device_class = OmniLinkBridge.MQTT.BinarySensor.DeviceClass.garage_door }},
|
||||
{ 7, new OmniLinkBridge.MQTT.OverrideZone { device_class = OmniLinkBridge.MQTT.BinarySensor.DeviceClass.motion }}
|
||||
};
|
||||
|
||||
Assert.AreEqual(override_zone.Count, Global.mqtt_discovery_override_zone.Count);
|
||||
foreach (KeyValuePair<int, OmniLinkBridge.MQTT.OverrideZone> pair in override_zone)
|
||||
{
|
||||
Global.mqtt_discovery_override_zone.TryGetValue(pair.Key, out OmniLinkBridge.MQTT.OverrideZone value);
|
||||
Assert.AreEqual(override_zone[pair.Key].device_class, value.device_class);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestNotifySettings()
|
||||
{
|
||||
// Default should be false
|
||||
Settings.LoadSettings(RequiredSettings());
|
||||
Assert.AreEqual(false, Global.verbose_unhandled);
|
||||
|
||||
// Check each setting correctly sets
|
||||
foreach (string setting in new string[] {
|
||||
"notify_area",
|
||||
"notify_message"
|
||||
})
|
||||
{
|
||||
List<string> lines = new List<string>(RequiredSettings());
|
||||
lines.Add($"{setting} = yes");
|
||||
Settings.LoadSettings(lines.ToArray());
|
||||
Assert.AreEqual(true, Global.GetValue(setting));
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestMailSettings()
|
||||
{
|
||||
// Default should be null
|
||||
Settings.LoadSettings(RequiredSettings());
|
||||
Assert.AreEqual(null, Global.mail_server);
|
||||
|
||||
// Test minimal settings
|
||||
List<string> lines = new List<string>(RequiredSettings());
|
||||
lines.AddRange(new string[]
|
||||
{
|
||||
"mail_server = localhost",
|
||||
"mail_port = 25",
|
||||
"mail_from = from@localhost",
|
||||
"mail_to = to1@localhost",
|
||||
"mail_to = to2@localhost"
|
||||
});
|
||||
Settings.LoadSettings(lines.ToArray());
|
||||
Assert.AreEqual("localhost", Global.mail_server);
|
||||
Assert.AreEqual(false, Global.mail_tls);
|
||||
Assert.AreEqual(25, Global.mail_port);
|
||||
Assert.AreEqual("from@localhost", Global.mail_from.Address);
|
||||
Assert.AreEqual(2, Global.mail_to.Length);
|
||||
Assert.AreEqual("to1@localhost", Global.mail_to[0].Address);
|
||||
Assert.AreEqual("to2@localhost", Global.mail_to[1].Address);
|
||||
|
||||
// Test additional settings
|
||||
lines.AddRange(new string[]
|
||||
{
|
||||
"mail_tls = yes",
|
||||
"mail_username = myuser",
|
||||
"mail_password = mypass"
|
||||
});
|
||||
Settings.LoadSettings(lines.ToArray());
|
||||
Assert.AreEqual(true, Global.mail_tls);
|
||||
Assert.AreEqual("myuser", Global.mail_username);
|
||||
Assert.AreEqual("mypass", Global.mail_password);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestProwlSettings()
|
||||
{
|
||||
// Test minimal settings
|
||||
List<string> lines = new List<string>(RequiredSettings());
|
||||
lines.AddRange(new string[]
|
||||
{
|
||||
"prowl_key = mykey1",
|
||||
"prowl_key = mykey2",
|
||||
});
|
||||
Settings.LoadSettings(lines.ToArray());
|
||||
Assert.AreEqual("mykey1", Global.prowl_key[0]);
|
||||
Assert.AreEqual("mykey2", Global.prowl_key[1]);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestPushoverSettings()
|
||||
{
|
||||
// Test minimal settings
|
||||
List<string> lines = new List<string>(RequiredSettings());
|
||||
lines.AddRange(new string[]
|
||||
{
|
||||
"pushover_token = mytoken",
|
||||
"pushover_user = myuser1",
|
||||
"pushover_user = myuser2",
|
||||
});
|
||||
Settings.LoadSettings(lines.ToArray());
|
||||
Assert.AreEqual("mytoken", Global.pushover_token);
|
||||
Assert.AreEqual("myuser1", Global.pushover_user[0]);
|
||||
Assert.AreEqual("myuser2", Global.pushover_user[1]);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue