-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added OpenKNX Toolbox library and WinForms test UI.
- Loading branch information
Andreas Breitschopp
committed
Jul 28, 2024
1 parent
81bd70b
commit 0a4a90b
Showing
26 changed files
with
1,523 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,4 +4,6 @@ bin/ | |
Check.* | ||
Check-Verify.* | ||
release/* | ||
debug/* | ||
debug/* | ||
.vs | ||
*.user |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
namespace OpenKNX.Toolbox.Lib.Data | ||
{ | ||
public class OpenKnxData | ||
{ | ||
public List<OpenKnxProject> Projects { get; set; } | ||
|
||
public OpenKnxData() | ||
{ | ||
Projects = []; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
namespace OpenKNX.Toolbox.Lib.Data | ||
{ | ||
public class OpenKnxProject : IComparable | ||
{ | ||
public long Id { get; set; } | ||
public string Name { get; set; } | ||
public List<OpenKnxRelease> Releases { get; set; } | ||
|
||
public OpenKnxProject(long id, string name) | ||
{ | ||
Id = id; | ||
Name = name; | ||
Releases = []; | ||
} | ||
|
||
public override string ToString() | ||
{ | ||
return Name; | ||
} | ||
|
||
public int CompareTo(object? obj) | ||
{ | ||
return string.Compare(ToString(), obj?.ToString(), StringComparison.CurrentCulture); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
namespace OpenKNX.Toolbox.Lib.Data | ||
{ | ||
public class OpenKnxRelease : IComparable | ||
{ | ||
public long Id { get; set; } | ||
public string Name { get; set; } | ||
public List<OpenKnxReleaseFile> Files { get; set; } | ||
|
||
public OpenKnxRelease(long id, string name) | ||
{ | ||
Id = id; | ||
Name = name; | ||
Files = []; | ||
} | ||
|
||
public override string ToString() | ||
{ | ||
return Name; | ||
} | ||
|
||
public int CompareTo(object? obj) | ||
{ | ||
return string.Compare(ToString(), obj?.ToString(), StringComparison.CurrentCulture); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
namespace OpenKNX.Toolbox.Lib.Data | ||
{ | ||
public class OpenKnxReleaseFile : IComparable | ||
{ | ||
public long Id { get; set; } | ||
public string Name { get; set; } | ||
public string DownloadUrl { get; set; } | ||
|
||
public OpenKnxReleaseFile(long id, string name, string downloadUrl) | ||
{ | ||
Id = id; | ||
Name = name; | ||
DownloadUrl = downloadUrl; | ||
} | ||
|
||
public override string ToString() | ||
{ | ||
return Name; | ||
} | ||
|
||
public int CompareTo(object? obj) | ||
{ | ||
return string.Compare(ToString(), obj?.ToString(), StringComparison.CurrentCulture); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
namespace OpenKNX.Toolbox.Lib.Data | ||
{ | ||
public class ReleaseContent | ||
{ | ||
public string AppName { get; set; } | ||
public string AppXmlFilePath { get; set; } | ||
public List<ReleaseContentFirmware> Firmwares { get; set; } | ||
|
||
public ReleaseContent(string appName, string appXmlFilePath) | ||
{ | ||
AppName = appName; | ||
AppXmlFilePath = appXmlFilePath; | ||
Firmwares = []; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
namespace OpenKNX.Toolbox.Lib.Data | ||
{ | ||
public class ReleaseContentFirmware | ||
{ | ||
public string Name { get; set; } | ||
public string FilePathUf2 { get; set; } | ||
|
||
public ReleaseContentFirmware(string name, string filePathUf2) | ||
{ | ||
Name = name; | ||
FilePathUf2 = filePathUf2; | ||
} | ||
|
||
public override string ToString() | ||
{ | ||
return Name; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
using System.Text.Json; | ||
using Octokit; | ||
using OpenKNX.Toolbox.Lib.Data; | ||
|
||
namespace OpenKNX.Toolbox.Lib | ||
{ | ||
public static class GitHubAccess | ||
{ | ||
private const string OPEN_KNX_ORG = "OpenKNX"; | ||
private const string OPEN_KNX_REPO_DEFAULT_START = "OAM-"; | ||
private const string OPEN_KNX_DATA_FILE_NAME = "OpenKNX.Toolbox.DataCache.json"; | ||
|
||
private static List<string> repositoryWhitelist = new List<string>() | ||
{ | ||
"SOM-UP", | ||
"GW-REG1-Dali", | ||
"SEN-UP1-8xTH", | ||
"BEM-GardenControl" | ||
}; | ||
|
||
/// <summary> | ||
/// Checks if a "OpenKnxData.json" file is present and not older than one day, otherwise download OpenKNX data from GitHub. | ||
/// </summary> | ||
/// <param name="dataDirectory">The directory to store the data file.</param> | ||
/// <returns>Returns a "OpenKnxData" object in case of success.</returns> | ||
public static async Task<OpenKnxData?> GetOpenKnxData(string dataDirectory) | ||
{ | ||
var dataFilePath = Path.Combine(dataDirectory, OPEN_KNX_DATA_FILE_NAME); | ||
if (File.Exists(dataFilePath)) | ||
{ | ||
if (File.GetLastWriteTimeUtc(dataFilePath) > DateTime.UtcNow.AddDays(-1)) | ||
{ | ||
using (var fileStream = new FileStream(dataFilePath, System.IO.FileMode.Open)) | ||
return await JsonSerializer.DeserializeAsync<OpenKnxData>(fileStream); | ||
} | ||
} | ||
|
||
var openKnxData = new OpenKnxData(); | ||
openKnxData.Projects = await GetOpenKnxProjects(); | ||
openKnxData.Projects.Sort(); | ||
|
||
using (var fileStream = new FileStream(dataFilePath, System.IO.FileMode.Create)) | ||
await JsonSerializer.SerializeAsync(fileStream, openKnxData); | ||
|
||
return openKnxData; | ||
} | ||
|
||
/// <summary> | ||
/// Load OpenKNX projects data from GitHub. | ||
/// </summary> | ||
/// <returns>The OpenKNX projects list.</returns> | ||
private static async Task<List<OpenKnxProject>> GetOpenKnxProjects() | ||
{ | ||
var openKnxProjects = new List<OpenKnxProject>(); | ||
var client = new GitHubClient(new ProductHeaderValue(OPEN_KNX_ORG)); | ||
|
||
var repositories = await client.Repository.GetAllForOrg(OPEN_KNX_ORG); | ||
foreach (var repository in repositories) | ||
{ | ||
if (!repository.Name.StartsWith(OPEN_KNX_REPO_DEFAULT_START) && | ||
!repositoryWhitelist.Contains(repository.Name)) | ||
continue; | ||
|
||
var openKnxProject = new OpenKnxProject(repository.Id, repository.Name); | ||
|
||
var releases = await client.Repository.Release.GetAll(repository.Id); | ||
foreach (var release in releases) | ||
{ | ||
if (string.IsNullOrEmpty(release.Name)) | ||
continue; | ||
|
||
var openKnxRelease = new OpenKnxRelease(release.Id, release.Name); | ||
|
||
foreach (var asset in release.Assets) | ||
{ | ||
if (!asset.Name.ToLower().EndsWith(".zip")) | ||
continue; | ||
|
||
openKnxRelease.Files.Add(new OpenKnxReleaseFile(asset.Id, asset.Name, asset.BrowserDownloadUrl)); | ||
} | ||
|
||
if (openKnxRelease.Files.Count > 0) | ||
{ | ||
openKnxRelease.Files.Sort(); | ||
openKnxProject.Releases.Add(openKnxRelease); | ||
} | ||
} | ||
|
||
if (openKnxProject.Releases.Count > 0) | ||
{ | ||
openKnxProject.Releases.Sort((a, b) => b.CompareTo(a)); | ||
openKnxProjects.Add(openKnxProject); | ||
} | ||
} | ||
|
||
return openKnxProjects; | ||
} | ||
|
||
/// <summary> | ||
/// Downloads a release ZIP file from GitHub. | ||
/// </summary> | ||
/// <param name="releaseFile">The "OpenKnxReleaseFile" object containing the download URL.</param> | ||
/// <returns>The file path where the downloaded ZIP is stored.</returns> | ||
/// <exception cref="FileNotFoundException"></exception> | ||
public static async Task<string> DownloadReleaseFile(OpenKnxReleaseFile releaseFile) | ||
{ | ||
using (var client = new HttpClient()) | ||
{ | ||
var response = await client.GetAsync(releaseFile.DownloadUrl); | ||
if (response.IsSuccessStatusCode) | ||
{ | ||
var contentStream = await response.Content.ReadAsStreamAsync(); | ||
var targetPath = Path.Combine(TempData.Instance.GetTempPath(), releaseFile.Name); | ||
var fileStream = new FileStream(targetPath, System.IO.FileMode.Create); | ||
await contentStream.CopyToAsync(fileStream).ContinueWith( | ||
(copyTask) => | ||
{ | ||
fileStream.Close(); | ||
}); | ||
|
||
return targetPath; | ||
} | ||
else | ||
{ | ||
throw new FileNotFoundException(); | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
using System.Text.RegularExpressions; | ||
using OpenKNXproducer; | ||
|
||
namespace OpenKNX.Toolbox.Lib | ||
{ | ||
public static class KnxProdBuilder | ||
{ | ||
/// <summary> | ||
/// Generates a KNXprod file. | ||
/// </summary> | ||
/// <param name="xmlFilePath">The path to the XML file the KNXprod will be generated from.</param> | ||
/// <param name="knxprodOutputPath">The output path of the generated KNXprod file.</param> | ||
/// <returns>True, if success, False otherwise.</returns> | ||
public static bool BuildKnxProd(string xmlFilePath, string knxprodOutputPath) | ||
{ | ||
var workingDir = KnxProdHelper.GetAbsWorkingDir(xmlFilePath); | ||
var xml = File.ReadAllText(xmlFilePath); | ||
var rs = new Regex("xmlns=\"(http:\\/\\/knx\\.org\\/xml\\/project\\/[0-9]{1,2})\""); | ||
var match = rs.Match(xml); | ||
var etsPath = KnxProdHelper.FindEtsPath(match.Groups[1].Value); | ||
return KnxProdHelper.ExportKnxprod(etsPath, workingDir, knxprodOutputPath, xmlFilePath, Path.GetFileName(xmlFilePath).Replace(".xml", ".baggages"), null, false, false) == 0; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Octokit" Version="13.0.1" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Compile Include="../Extensions.cs"/> | ||
<Compile Include="../KnxProdHelper.cs"/> | ||
<Compile Include="../Signing/ApplicationSigner.cs" Link="Signing/ApplicationSigner.cs"/> | ||
<Compile Include="../Signing/CatalogIdPatcher.cs" Link="Signing/CatalogIdPatcher.cs"/> | ||
<Compile Include="../Signing/HardwareSigner.cs" Link="Signing/HardwareSigner.cs"/> | ||
<Compile Include="../Signing/XmlSigner.cs" Link="Signing/XmlSigner.cs"/> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
using System.Text.RegularExpressions; | ||
using OpenKNX.Toolbox.Lib.Data; | ||
|
||
namespace OpenKNX.Toolbox.Lib | ||
{ | ||
public static class ReleaseContentHelper | ||
{ | ||
/// <summary> | ||
/// Reads the "content.xml" file from a release. | ||
/// </summary> | ||
/// <param name="releaseDirectory">The release directory containing a "data\content.xml" file.</param> | ||
/// <returns>Returns a "ReleaseContent" object.</returns> | ||
public static ReleaseContent GetReleaseContent(string releaseDirectory) | ||
{ | ||
var contentXmlPath = Path.Combine(releaseDirectory, "data", "content.xml"); | ||
var contentXml = File.ReadAllText(contentXmlPath); | ||
|
||
var rs = new Regex("<ETSapp Name=\"(.*)\" XmlFile=\"(.*)\" \\/>"); | ||
var match = rs.Match(contentXml); | ||
var appName = match.Groups[1].Value; | ||
var appXmlFileName = Path.Combine(Path.GetDirectoryName(contentXmlPath), match.Groups[2].Value); | ||
|
||
var appXmlFilePath = Path.Combine(releaseDirectory, "data", appXmlFileName); | ||
var releaseContent = new ReleaseContent(appName, appXmlFilePath); | ||
|
||
rs = new Regex("<Product Name=\"(.*)\" Firmware=\"(.*)\" Processor=\"(.*)\" \\/>"); | ||
foreach (Match rsMatch in rs.Matches(contentXml)) | ||
{ | ||
if (rsMatch.Groups[3].Value != "RP2040") | ||
continue; | ||
|
||
var firmwareName = rsMatch.Groups[1].Value; | ||
var filePathUf2 = Path.Combine(releaseDirectory, "data", rsMatch.Groups[2].Value); | ||
var firmware = new ReleaseContentFirmware(firmwareName, filePathUf2); | ||
releaseContent.Firmwares.Add(firmware); | ||
} | ||
|
||
return releaseContent; | ||
} | ||
} | ||
} |
Oops, something went wrong.