Skip to content

Commit

Permalink
Merge branch 'release/0.5.0' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
charliefoxtwo committed Dec 17, 2022
2 parents c9bd934 + 3bbba45 commit 37a8cb2
Show file tree
Hide file tree
Showing 12 changed files with 119 additions and 72 deletions.
2 changes: 1 addition & 1 deletion Configuration/Configuration.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Virpil.Communicator" Version="2.0.0" />
<PackageReference Include="Virpil.Communicator" Version="3.1.0" />
</ItemGroup>

<ItemGroup>
Expand Down
27 changes: 22 additions & 5 deletions Configuration/DeviceConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
// ReSharper disable ClassNeverInstantiated.Global
#pragma warning disable 8618

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Core;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Virpil.Communicator;

Expand All @@ -16,12 +18,27 @@ public class DeviceConfiguration
public BaseTrigger? Trigger { get; set; }
public Dictionary<string, Device>? Devices { get; set; }

public static Dictionary<string, DeviceConfiguration?> GetDeviceConfigurations()
public static IEnumerable<DeviceConfiguration> GetDeviceConfigurations(ILogger<DeviceConfiguration> log)
{
return Directory.EnumerateFiles("Configuration", "*.json", SearchOption.AllDirectories)
.Select(f => new KeyValuePair<string, DeviceConfiguration?>(f.Split('/').Last(), JsonConvert.DeserializeObject<DeviceConfiguration>(File.ReadAllText(f))))
.Where(kvp => kvp.Key != "ViLA.json")
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
foreach (var filePath in Directory.EnumerateFiles("Configuration", "*.json", SearchOption.AllDirectories))
{
var fileName = Path.GetFileName(filePath);
if (fileName == "ViLA.json") continue;

DeviceConfiguration? data;
try
{
data = JsonConvert.DeserializeObject<DeviceConfiguration>(File.ReadAllText(filePath));
}
catch (Exception ex)
{
log.LogWarning("Error while parsing config file [{File}], skipping...", fileName);
log.LogDebug("Error: {Error}", ex);
continue;
}

if (data is not null) yield return data;
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion Configuration/Schema/ActionConfiguration.json.schema
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@
"$ref": "#/definitions/ledAction/definitions/action/definitions/trigger"
},
"devices": {
"description": "All devices and device actions go here. The key is the device's USB PID.",
"description": "All devices and device actions go here. The key is the device's USB PID in hex form, with the device name appended and separated by a vertical bar | if more than one identical PID exists.",
"type": "object",
"additionalProperties": {
"type": "object",
Expand Down
8 changes: 8 additions & 0 deletions Configuration/Schema/ViLAConfiguration.json.schema
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@
"type": "boolean",
"default": false
},
"additionalVids" : {
"description": "Extra VIDs to be checked (in hex format) in addition to the Virpil default 0x3344.",
"type": "array",
"items": {
"type": "string"
},
"examples": [[ "12AB" ], [ "A1B9", "12AB" ]]
},
"disabledPlugins": {
"description": "Plugins which should not be loaded on the next run.",
"type": "array",
Expand Down
17 changes: 13 additions & 4 deletions Configuration/VilaConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class VilaConfiguration
public LogLevel? LogLevel { get; set; }
public bool CheckUpdates { get; set; } = true;
public bool CheckPrerelease { get; set; }
public HashSet<string> AdditionalVids { get; set; } = new();
public HashSet<string> DisabledPlugins { get; set; } = new();


Expand All @@ -33,16 +34,24 @@ public VilaConfiguration Append(VilaConfiguration otherVilaConfiguration)

if (otherVilaConfiguration.CheckPrerelease) CheckPrerelease = otherVilaConfiguration.CheckPrerelease;
if (otherVilaConfiguration.CheckUpdates) CheckUpdates = otherVilaConfiguration.CheckUpdates;
AdditionalVids.UnionWith(otherVilaConfiguration.AdditionalVids);
DisabledPlugins.UnionWith(otherVilaConfiguration.DisabledPlugins);

return this;
}

public static VilaConfiguration? GetVilaConfiguration()
{
return Directory.EnumerateFiles("Configuration", "ViLA.json", SearchOption.AllDirectories).AsParallel()
.Select(f => JsonConvert.DeserializeObject<VilaConfiguration>(File.ReadAllText(f)))
.Where(c => c != null)
.Aggregate((s, t) => s!.Append(t!));
try
{
return Directory.EnumerateFiles("Configuration", "ViLA.json", SearchOption.AllDirectories).AsParallel()
.Select(f => JsonConvert.DeserializeObject<VilaConfiguration>(File.ReadAllText(f)))
.Where(c => c != null)
.Aggregate((s, t) => s!.Append(t!));
}
catch (Exception _)
{
return null;
}
}
}
1 change: 1 addition & 0 deletions Core/Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>default</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,7 @@ Not directly, no. You can get creative with the plugin and the Ids in your confi

## Local Development

If making package changes (highly discouraged) it is important to regenerate the plugin_manifest.xml file. This can be done with the following command: `dotnet store -m ViLA.csproj --runtime win-x64 -f net5.0`

This command will output `%userprofile%/.dotnet/store/x64/net5.0/artifact.xml`, among other things. Make sure to replace the current plugin_manifest.xml file with this one.
If making package changes (highly discouraged) it is important to regenerate the plugin_manifest.xml file. There used to be a tool to do this, but development of it stopped with .NET 5 and so the file must now be maintained by hand. Hooray!

## Acknowledgements

Expand Down
8 changes: 5 additions & 3 deletions ViLA/DeviceAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ namespace ViLA;

public class DeviceAction<T> where T : BaseTrigger
{
public ushort Device { get; }
public ushort DevicePid { get; }
public string? DeviceName { get; }
public T Trigger { get; }
public string Color { get; }
public Target Target { get; }

public DeviceAction(string color, T trigger, Target target, ushort device)
public DeviceAction(string color, T trigger, Target target, ushort devicePid, string? deviceName)
{
Color = color;
Trigger = trigger;
Target = target;
Device = device;
DevicePid = devicePid;
DeviceName = deviceName;
}
}
34 changes: 22 additions & 12 deletions ViLA/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
Expand All @@ -21,20 +22,18 @@ public class Program

public static async Task Main(string[] args)
{

var cfg = VilaConfiguration.GetVilaConfiguration();

var loggerFactory = LoggerFactory.Create(b => ConfigureLogger(b, cfg?.LogLevel ?? LogLevel.Information));

_log = loggerFactory.CreateLogger<Program>();

if (cfg is null)
{
var lf = LoggerFactory.Create(c => c.SetMinimumLevel(LogLevel.Information).AddConsole());

lf.CreateLogger<Program>().LogCritical("Config files are empty or error loading config files, exiting...");
_log.LogCritical("ViLA.json files are empty or error loading ViLA.json files, exiting...");
return;
}

var loggerFactory = LoggerFactory.Create(c => c.SetMinimumLevel(cfg.LogLevel ?? LogLevel.Information).AddConsole());
_log = loggerFactory.CreateLogger<Program>();

await CheckProgramVersion(cfg.CheckPrerelease);

var plugins = new List<PluginBase.PluginBase>();
Expand All @@ -44,7 +43,7 @@ public static async Task Main(string[] args)
plugins.Add(plugin);
}

var monitor = VirpilMonitor.Initialize(loggerFactory);
var monitor = VirpilMonitor.Initialize(loggerFactory, cfg.AdditionalVids.Select(vid => ushort.Parse(vid, NumberStyles.HexNumber)));
var devices = monitor.AllConnectedVirpilDevices;

_log.LogInformation("Detected {DeviceNumber} devices", devices.Count);
Expand All @@ -63,16 +62,26 @@ public static async Task Main(string[] args)
}
}

var deviceConfigs = DeviceConfiguration.GetDeviceConfigurations();
var deviceConfigs = DeviceConfiguration.GetDeviceConfigurations(loggerFactory.CreateLogger<DeviceConfiguration>());

using var r = new Runner(monitor, deviceConfigs.Values.Where(c => c != null).Select(c => c!), plugins,
loggerFactory.CreateLogger<Runner>());
using var r = new Runner(monitor, deviceConfigs, plugins, loggerFactory.CreateLogger<Runner>());

await r.Start(loggerFactory);

await Task.Delay(-1, new CancellationToken());
}

private static void ConfigureLogger(ILoggingBuilder builder, LogLevel logLevel)
{
builder.SetMinimumLevel(logLevel).AddConsole().AddFile(string.Empty,
options =>
{
options.MinLevel = logLevel;
var fileName = $"log/ViLA_{DateTime.Now:yyyy-MM-ddTHHmmss}.log";
options.FormatLogFileName = _ => fileName;
});
}

private static async IAsyncEnumerable<PluginBase.PluginBase> LoadPlugins(IReadOnlySet<string> disabledPlugins, bool checkUpdates = true, bool checkPrerelease = false)
{
if (!Directory.Exists("./Plugins")) Directory.CreateDirectory("./Plugins");
Expand Down Expand Up @@ -153,9 +162,10 @@ private static async Task CheckVersionAgainstGithub(string name, Version current
{
response = await client.GetAsync<List<GithubReleaseResponse>>(request);
}
catch (JsonSerializationException ex)
catch (Exception ex)
{
// probably a github rate limit. we'll just skip for now
// network can also be offline
return;
}

Expand Down
28 changes: 14 additions & 14 deletions ViLA/Runner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ public Runner(VirpilMonitor deviceMonitor, IEnumerable<DeviceConfiguration> devi

foreach (var (deviceId, device) in deviceConfig.Devices)
{
var deviceShort = ushort.Parse(deviceId, NumberStyles.HexNumber);
var parts = deviceId.Split('|');
var deviceShort = ushort.Parse(parts[0], NumberStyles.HexNumber);
var deviceName = parts.Length < 2 ? null : string.Concat(parts[1..]);
foreach (var (boardType, boardActions) in device)
{
foreach (var (ledNumber, ledActions) in boardActions)
Expand All @@ -48,7 +50,7 @@ public Runner(VirpilMonitor deviceMonitor, IEnumerable<DeviceConfiguration> devi
var trigger = deviceConfig.Trigger is not null
? new AndTrigger(new List<BaseTrigger> { deviceConfig.Trigger, action.Trigger })
: action.Trigger;
SetUpTrigger(trigger, action, ledNumber, boardType, deviceShort);
SetUpTrigger(trigger, action, ledNumber, boardType, deviceShort, deviceName);
}
catch (ArgumentException)
{
Expand All @@ -61,7 +63,7 @@ public Runner(VirpilMonitor deviceMonitor, IEnumerable<DeviceConfiguration> devi
}
}

private void SetUpTrigger(BaseTrigger trigger, LedAction ledAction, int ledNumber, BoardType boardType, ushort deviceShort)
private void SetUpTrigger(BaseTrigger trigger, LedAction ledAction, int ledNumber, BoardType boardType, ushort devicePid, string? deviceName)
{
foreach (var key in trigger.TriggerStrings)
{
Expand All @@ -70,7 +72,7 @@ private void SetUpTrigger(BaseTrigger trigger, LedAction ledAction, int ledNumbe
_actions[key] = new List<DeviceAction<BaseTrigger>>();
}

_actions[key].Add(new DeviceAction<BaseTrigger>(ledAction.Color, trigger, new Target(boardType, ledNumber), deviceShort));
_actions[key].Add(new DeviceAction<BaseTrigger>(ledAction.Color, trigger, new Target(boardType, ledNumber), devicePid, deviceName));
}
}

Expand Down Expand Up @@ -115,26 +117,24 @@ private void TriggerActionForValue(IReadOnlyDictionary<string, List<DeviceAction
_log.LogTrace("got data {Data} for {Id}", (object) value, id);
_state[id] = value;

foreach (var action in actions.Where(action => action.Trigger.ShouldTrigger(_state)))
{
if (!_monitor.TryGetDevice(action.Device, out var device)) continue;

_log.LogDebug("Triggering {Id}", id);
var (red, green, blue) = action.Color.ToLedPowers();
device.SendCommand(action.Target.BoardType, action.Target.LedNumber, red, green, blue);
}
SendCommands(actions.Where(action => action.Trigger.ShouldTrigger(_state)));
}

private void TriggerAction(string id)
{
if (!_actions.TryGetValue(id, out var actions)) return; // nothing for this id, then leave

_log.LogTrace("got trigger for {Id}", id);

SendCommands(actions);
}

private void SendCommands(IEnumerable<DeviceAction<BaseTrigger>> actions)
{
foreach (var action in actions)
{
if (!_monitor.TryGetDevice(action.Device, out var device)) continue;
if (!_monitor.TryGetDevice(action.DevicePid, action.DeviceName, out var device)) continue;

_log.LogDebug("Triggering {Id}", id);
var (red, green, blue) = action.Color.ToLedPowers();
device.SendCommand(action.Target.BoardType, action.Target.LedNumber, red, green, blue);
}
Expand Down
19 changes: 10 additions & 9 deletions ViLA/ViLA.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,21 @@
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<AssemblyVersion>0.4.0</AssemblyVersion>
<FileVersion>0.4.0</FileVersion>
<AssemblyVersion>0.5.0</AssemblyVersion>
<FileVersion>0.5.0</FileVersion>
<IsPackable>false</IsPackable>
<LangVersion>default</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="McMaster.NETCore.Plugins" Version="1.3.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
<PackageReference Include="RestSharp" Version="106.11.7" />
<PackageReference Include="RestSharp.Serializers.NewtonsoftJson" Version="106.11.7" />
<PackageReference Include="ViLA.PluginBase" Version="2.1.0" />
<PackageReference Include="Virpil.Communicator" Version="2.0.0" />
<PackageReference Include="McMaster.NETCore.Plugins" Version="1.4.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
<PackageReference Include="NReco.Logging.File" Version="1.1.5" />
<PackageReference Include="RestSharp" Version="108.0.1" />
<PackageReference Include="RestSharp.Serializers.NewtonsoftJson" Version="108.0.1" />
<PackageReference Include="ViLA.PluginBase" Version="2.1.1" />
<PackageReference Include="Virpil.Communicator" Version="3.1.0" />
</ItemGroup>

<ItemGroup>
Expand Down
41 changes: 21 additions & 20 deletions plugin_manifest.xml
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
<StoreArtifacts>
<Package Id="Newtonsoft.Json" Version="13.0.1" />
<Package Id="HidSharp" Version="2.1.0" />
<Package Id="Microsoft.Extensions.DependencyInjection" Version="5.0.0" />
<Package Id="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0" />
<Package Id="Microsoft.Extensions.Logging" Version="5.0.0" />
<Package Id="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
<Package Id="Microsoft.Extensions.Options" Version="5.0.0" />
<Package Id="Microsoft.Extensions.Primitives" Version="5.0.0" />
<Package Id="Virpil.Communicator" Version="2.0.0" />
<Package Id="McMaster.NETCore.Plugins" Version="1.3.1" />
<Package Id="Microsoft.DotNet.PlatformAbstractions" Version="3.1.0" />
<Package Id="Microsoft.Extensions.DependencyModel" Version="3.1.0" />
<Package Id="System.Text.Json" Version="4.7.0" />
<Package Id="Microsoft.Extensions.Configuration" Version="5.0.0" />
<Package Id="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
<Package Id="Microsoft.Extensions.Configuration.Binder" Version="5.0.0" />
<Package Id="Microsoft.Extensions.Logging.Configuration" Version="5.0.0" />
<Package Id="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
<Package Id="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0" />
<Package Id="RestSharp" Version="106.11.7" />
<Package Id="Newtonsoft.Json" Version="12.0.3" />
<Package Id="RestSharp.Serializers.NewtonsoftJson" Version="106.11.7" />
<Package Id="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
<Package Id="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
<Package Id="Microsoft.Extensions.Logging" Version="6.0.0" />
<Package Id="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0" />
<Package Id="Microsoft.Extensions.Options" Version="6.0.0" />
<Package Id="Microsoft.Extensions.Primitives" Version="6.0.0" />
<Package Id="Virpil.Communicator" Version="3.1.0" />
<Package Id="McMaster.NETCore.Plugins" Version="1.4.0" />
<Package Id="Microsoft.DotNet.PlatformAbstractions" Version="3.1.6" />
<Package Id="Microsoft.Extensions.DependencyModel" Version="5.0.0" />
<Package Id="System.Text.Json" Version="6.0.5" />
<Package Id="Microsoft.Extensions.Configuration" Version="6.0.0" />
<Package Id="Microsoft.Extensions.Configuration.Abstractions" Version="6.0.0" />
<Package Id="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
<Package Id="Microsoft.Extensions.Logging.Configuration" Version="6.0.0" />
<Package Id="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
<Package Id="Microsoft.Extensions.Options.ConfigurationExtensions" Version="6.0.0" />
<Package Id="RestSharp" Version="108.0.1" />
<Package Id="Newtonsoft.Json" Version="13.0.1" />
<Package Id="RestSharp.Serializers.NewtonsoftJson" Version="108.0.1" />
<Package Id="ViLA.PluginBase" Version="2.1.0" />
<Package Id="NReco.Logging.File" Version="1.1.5" />
</StoreArtifacts>

0 comments on commit 37a8cb2

Please sign in to comment.