diff --git a/csharp/app/VenusFirmwareCiDaemon/FirmwareCiDaemon.csproj b/csharp/app/VenusFirmwareCiDaemon/FirmwareCiDaemon.csproj
deleted file mode 100644
index ab56dceed..000000000
--- a/csharp/app/VenusFirmwareCiDaemon/FirmwareCiDaemon.csproj
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
- InnovEnergy.Server.FirmwareCiDaemon
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/csharp/app/VenusFirmwareCiDaemon/src/Branch.cs b/csharp/app/VenusFirmwareCiDaemon/src/Branch.cs
deleted file mode 100644
index e0954371b..000000000
--- a/csharp/app/VenusFirmwareCiDaemon/src/Branch.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-namespace InnovEnergy.Server.FirmwareCiDaemon;
-
-public enum Branch
-{
- Release,
- Develop,
- Victron,
-}
-
-public static class BranchExtensions
-{
- public static String GetName(this Branch branch) => branch switch
- {
- Branch.Victron => "venus.victron",
- Branch.Release => "venus.release",
- Branch.Develop => "venus",
- _ => throw new Exception($"Unsupported branch: {branch}")
- };
-
-
-}
\ No newline at end of file
diff --git a/csharp/app/VenusFirmwareCiDaemon/src/Build.cs b/csharp/app/VenusFirmwareCiDaemon/src/Build.cs
deleted file mode 100644
index bf93a7008..000000000
--- a/csharp/app/VenusFirmwareCiDaemon/src/Build.cs
+++ /dev/null
@@ -1,295 +0,0 @@
-using System.Text.RegularExpressions;
-using CliWrap;
-using InnovEnergy.Lib.Utils;
-using static InnovEnergy.Server.FirmwareCiDaemon.Logger;
-using static InnovEnergy.Server.FirmwareCiDaemon.ExitException;
-
-namespace InnovEnergy.Server.FirmwareCiDaemon;
-
-public record Build
-{
- private static readonly Regex RxTimestamp = new Regex(@"\d{14}");
- private static readonly Regex RxVersion = new Regex(@"v\d+\.\d+(~\w+)?");
-
- private const Int32 MaxPublishedSwus = 12;
-
- public Device Device { get; init; }
- public String VeVersion { get; init; }
- public Branch Branch { get; init; }
- public String Comment { get; init; }
- public String Hash { get; init; }
-
- public String ShortHash => Hash[..6];
-
- public Channel Channel => Branch switch
- {
- Branch.Victron => Channel.Testing,
- Branch.Release => Channel.Release,
- Branch.Develop => Channel.Develop,
- _ => throw new Exception($"Unsupported branch: {Branch}")
- };
-
- public String VersionId => Branch switch
- {
- Branch.Victron => $"{VeVersion}~victron",
- Branch.Release => $"{VeVersion}~{Comment}",
- Branch.Develop => $"{VeVersion}~{ShortHash}",
- _ => throw new Exception($"Unsupported branch: {Branch}")
- };
-
- public static Build Prepare(CommitInfo ie, (Device device, String veVersion) ve)
- {
- return new Build
- {
- Device = ve.device,
- VeVersion = ve.veVersion,
- Branch = ie.Branch,
- Comment = ie.Comment,
- Hash = ie.Hash
- };
- }
-
-
- public void Execute()
- {
- Log();
- Log("======================================================");
- Log("Starting build");
- Log("======================================================");
- Log();
- Log($"VE Version: {VeVersion}");
- Log($"Channel : {Channel}");
- Log($"Device : {Device}");
- Log($"Branch : {Branch}");
- Log($"Comment : {Comment}");
- Log($"Version ID: {VersionId}");
- Log($"SWU Name : {Device.SwuName()}");
- Log($"Hash : {Hash}");
- Log();
- Log("======================================================");
- Log();
-
- using var veBaseSwuFile = FwSource.Victron.GetLatestSwuPath(Channel.Release, Device).Apply(DownloadFile);
- using var ieRepo = Fossil.Checkout(Branch);
- using var releaseSwu = MergeSwu(veBaseSwuFile, ieRepo.FirmwareDirectory, Device, VersionId);
-
- var publishedSwu = PublishSwu(Device, Channel, releaseSwu);
-
- RemoveOldFiles(Device, Channel);
-
- var zipPath = Channel.ZipPath();
- var removeGlob = Device.SwuBase() + "*";
-
- if (zipPath is null)
- return;
-
- Log($"Updating {zipPath[Program.IeBasePath.Length..]}");
-
- zipPath.RemoveFromZip(removeGlob);
- zipPath.AddToZip(publishedSwu);
- }
-
- public static Disposable DownloadFile(String url)
- {
- var fileName = Path.GetFileName(url);
-
- var downloadedFile = FileSystem.CreateTempFile(fileName);
-
- Log($"downloading {url}");
-
- var curl = Cli
- .Wrap("curl")
- .WithArguments(url)
- .PipeToFile(downloadedFile);
-
- if (curl.exitCode != 0)
- Exit("Failed to download " + url);
-
- return downloadedFile;
- }
-
- private static void UpdateVersionFile(String fwDir, String version, String timestamp, String file)
- {
- Log($"updating {file}");
-
- var fwFile = fwDir.AppendPath(file);
-
- if (!FileSystem.Local.FileExists(fwFile))
- Exit($"Cannot find {fwFile}");
-
- var contents = File.ReadAllText(fwFile);
-
- contents = RxTimestamp.Replace(contents, timestamp);
- contents = RxVersion.Replace(contents, version);
-
- try
- {
- File.WriteAllText(fwFile, contents);
- }
- catch
- {
- Exit($"Failed to write to {fwFile}");
- }
- }
-
- private static void PatchIeFiles(String fossilDir, String mountDir)
- {
- Log("applying changes");
-
- var (exitCode, stdOut, stdErr) = Cli
- .Wrap("rsync")
- .WithArguments($"-r -t -v -l -i -u -I {fossilDir}/ {mountDir}") // that / is important!
- .ExecuteSync();
-
- if (exitCode != 0)
- Exit($"Failed to apply changes!\n{stdErr}\n{stdOut}");
- }
-
-
-
- private static Disposable Unzip(String ext4GzFile)
- {
- var ext4GzFileName = Path.GetFileName(ext4GzFile);
- Log($"extracting {ext4GzFileName}");
-
- var ext4File = ext4GzFileName
- .RemoveSuffix(".gz")
- .Apply(FileSystem.CreateTempFile);
-
- var zcat = Cli
- .Wrap("zcat")
- .WithArguments(ext4GzFile)
- .PipeToFile(ext4File);
-
- if (zcat.exitCode != 0)
- {
- ext4File.Dispose();
- Exit("Failed to extract " + ext4GzFile);
- }
-
- return ext4File;
- }
-
- private static Disposable Mount(String ext4File)
- {
- var ext4FileName = Path.GetFileName(ext4File);
- Log($"mounting {ext4FileName}");
-
- var mountDir = FileSystem.CreateTmpDir();
-
- var mount = Cli
- .Wrap("mount")
- .WithArguments($"-o loop -t ext4 {ext4File} {mountDir}")
- .ExecuteSync();
-
- if (mount.exitCode != 0)
- {
- Log($"\nFailed to mount {ext4File} on {mountDir}:\n{mount.stdErr}");
-
- mountDir.Dispose();
- Exit($"\nFailed to mount {ext4File}:\n{mount.stdErr}");
- }
-
- return mountDir.BeforeDisposeDo(Unmount);
-
- void Unmount()
- {
- Log($"unmounting {ext4FileName}");
-
- var umount = Cli
- .Wrap("umount")
- .WithArguments(mountDir)
- .ExecuteSync();
-
- if (umount.exitCode != 0)
- Exit($"Failed to unmount {mountDir}\n{umount.stdErr}");
- }
- }
-
- private static void ApplyChanges(String ieFirmwareDir,
- String ext4File,
- String timestamp,
- String version)
- {
- using var mountDir = Mount(ext4File); // IMPORTANT: must unmount (dispose) before zipping ext4 file again!
-
- PatchIeFiles(ieFirmwareDir, mountDir);
-
- UpdateVersionFile(mountDir, version, timestamp, "/etc/issue");
- UpdateVersionFile(mountDir, version, timestamp, "/etc/issue.net");
- UpdateVersionFile(mountDir, version, timestamp, "/etc/version");
- UpdateVersionFile(mountDir, version, timestamp, "/opt/victronenergy/version");
- }
-
-
- private static void UpdateSymlink(String newSwuFile, String newSwuLink)
- {
- var ln = Cli
- .Wrap("ln")
- .WithArguments($"-sfn {newSwuFile} {newSwuLink}")
- .ExecuteSync();
-
- if (ln.exitCode != 0)
- Exit($"failed to update symlink {newSwuLink}");
- }
-
-
- private static void RemoveOldFiles(Device device, Channel channel)
- {
- var oldFiles = Directory
- .GetFiles(FwSource.InnovEnergy.GetDirectory(channel, device))
- .Where(f => f.EndsWith(".swu"))
- .OrderByDescending(File.GetCreationTimeUtc)
- .Skip(MaxPublishedSwus);
-
- foreach (var file in oldFiles)
- {
- Log($"Deleting old swu file {file.Substring(Program.IeBasePath.Length)}");
- File.Delete(file);
- }
- }
-
- private static String PublishSwu(Device device, Channel channel, String releaseSwu)
- {
- var swuFileName = Path.GetFileName(releaseSwu);
- var newSwuFile = FwSource.InnovEnergy.GetDirectory(channel, device).AppendPath(swuFileName);
- var newSwuLink = FwSource.InnovEnergy.GetLatestSwuPath(channel, device);
-
- Log($"publishing {newSwuFile[Program.IeBasePath.Length..]}");
-
- new FileInfo(newSwuFile).Directory?.Create(); // create dir if not exits
- File.Move(releaseSwu, newSwuFile);
-
- UpdateSymlink(newSwuFile, newSwuLink);
-
- return newSwuFile;
- }
-
-
- private static Disposable MergeSwu(String victronBaseSwuFile,
- String ieFirmwareDir,
- Device device,
- String version)
- {
- var timestamp = DateTime.Now.ToString("yyyyMMddHHmmss");
-
- using var cpioDir = Cpio.Extract(victronBaseSwuFile);
-
- var ext4GzFile = cpioDir.Value.AppendPath(device.ExtGzFileName());
-
- using var ext4File = Unzip(ext4GzFile);
-
- UpdateVersionFile(cpioDir, version, timestamp, "/sw-description");
- ApplyChanges(ieFirmwareDir, ext4File, timestamp, version);
-
- Zip.GZip(ext4File, ext4GzFile);
-
- var mergedSwuFile = device
- .LongSwuFileName(timestamp, version)
- .Apply(FileSystem.CreateTempFile);
-
- Cpio.Write(cpioDir, mergedSwuFile);
-
- return mergedSwuFile;
- }
-}
\ No newline at end of file
diff --git a/csharp/app/VenusFirmwareCiDaemon/src/Channel.cs b/csharp/app/VenusFirmwareCiDaemon/src/Channel.cs
deleted file mode 100644
index c59edfe63..000000000
--- a/csharp/app/VenusFirmwareCiDaemon/src/Channel.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using InnovEnergy.Lib.Utils;
-
-namespace InnovEnergy.Server.FirmwareCiDaemon;
-
-public enum Channel
-{
- Release,
- Candidate,
- Testing,
- Develop
-}
-
-public static class ChannelExtensions
-{
- public static String GetName(this Channel channel)
- {
- return Enum.GetName(typeof(Channel), channel)?.ToLower()!;
- }
-
- public static String? ZipPath(this Channel channel)
- {
- if (channel is Channel.Candidate or Channel.Develop)
- return null;
-
- var fileName = channel is Channel.Release
- ? "release.zip"
- : "victron.zip";
-
- return Program.IeBasePath.AppendPath("venus").AppendPath(fileName);
- }
-}
\ No newline at end of file
diff --git a/csharp/app/VenusFirmwareCiDaemon/src/CliExtensions.cs b/csharp/app/VenusFirmwareCiDaemon/src/CliExtensions.cs
deleted file mode 100644
index 8fe61f3b1..000000000
--- a/csharp/app/VenusFirmwareCiDaemon/src/CliExtensions.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using System.Text;
-using CliWrap;
-
-namespace InnovEnergy.Server.FirmwareCiDaemon;
-
-public static class CliExtensions
-{
-
- // TODO: obsolete, use ExecuteBufferedAsync
- public static (Int32 exitCode, String stdOut, String stdErr) ExecuteSync(this Command cmd)
- {
- var stdErr = new StringBuilder();
- var stdOut = new StringBuilder();
-
- var r = cmd
- .WithStandardOutputPipe(PipeTarget.ToStringBuilder(stdOut))
- .WithStandardErrorPipe(PipeTarget.ToStringBuilder(stdErr))
- .WithValidation(CommandResultValidation.None)
- .ExecuteAsync()
- .Task
- .Result;
-
- return (r.ExitCode, stdOut.ToString(), stdErr.ToString());
- }
-
- public static (Int32 exitCode, String stdErr) PipeToFile(this Command cmd, String file)
- {
- var stdErr = new StringBuilder();
-
- var r = cmd
- .WithStandardOutputPipe(PipeTarget.ToFile(file))
- .WithStandardErrorPipe(PipeTarget.ToStringBuilder(stdErr))
- .WithValidation(CommandResultValidation.None)
- .ExecuteAsync()
- .Task
- .Result;
-
- return (r.ExitCode, stdErr.ToString());
- }
-
-}
\ No newline at end of file
diff --git a/csharp/app/VenusFirmwareCiDaemon/src/Commit.cs b/csharp/app/VenusFirmwareCiDaemon/src/Commit.cs
deleted file mode 100644
index c45e467b8..000000000
--- a/csharp/app/VenusFirmwareCiDaemon/src/Commit.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using InnovEnergy.Lib.Utils;
-
-namespace InnovEnergy.Server.FirmwareCiDaemon;
-
-public class Commit : Disposable
-{
- public String Directory { get; }
- public String FirmwareDirectory => Directory.AppendPath("firmware");
-
- public Commit(Disposable directory) : base(directory.Dispose)
- {
- Directory = directory;
- }
-
-}
\ No newline at end of file
diff --git a/csharp/app/VenusFirmwareCiDaemon/src/CommitInfo.cs b/csharp/app/VenusFirmwareCiDaemon/src/CommitInfo.cs
deleted file mode 100644
index f4938f723..000000000
--- a/csharp/app/VenusFirmwareCiDaemon/src/CommitInfo.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace InnovEnergy.Server.FirmwareCiDaemon;
-
-public record CommitInfo
-{
- public String Hash { get; init; }
- public String Comment { get; init; }
- public Branch Branch { get; init; }
-}
\ No newline at end of file
diff --git a/csharp/app/VenusFirmwareCiDaemon/src/Cpio.cs b/csharp/app/VenusFirmwareCiDaemon/src/Cpio.cs
deleted file mode 100644
index 262d4028e..000000000
--- a/csharp/app/VenusFirmwareCiDaemon/src/Cpio.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-using CliWrap;
-using InnovEnergy.Lib.Utils;
-using static InnovEnergy.Server.FirmwareCiDaemon.ExitException;
-using static InnovEnergy.Server.FirmwareCiDaemon.Logger;
-
-namespace InnovEnergy.Server.FirmwareCiDaemon;
-
-public static class Cpio
-{
- public static void Write(String cpioDir, String swuFile)
- {
- var swuFileName = Path.GetFileName(swuFile);
-
- Log($"writing {swuFileName}");
-
- // ls | cpio -o -H crc > "../$swu" 2>/dev/null
-
- var ls = Cli
- .Wrap("ls")
- .WithWorkingDirectory(cpioDir);
-
- var cpio = Cli
- .Wrap("cpio")
- .WithArguments("-o -H crc")
- .WithStandardOutputPipe(PipeTarget.ToFile(swuFile))
- .WithWorkingDirectory(cpioDir);
-
- var lsCpio = (ls | cpio).ExecuteAsync().Task.Result;
-
- if (lsCpio.ExitCode != 0)
- Exit($"Failed to write {swuFileName}");
- }
-
- public static Disposable Extract(String swuFile)
- {
- Log($"extracting {Path.GetFileName(swuFile)}");
-
- var cpioDir = FileSystem.CreateTmpDir();
-
- var cpio = Cli
- .Wrap("cpio")
- .WithArguments("-id")
- .WithStandardInputPipe(PipeSource.FromFile(swuFile))
- .WithWorkingDirectory(cpioDir)
- .ExecuteSync();
-
- if (cpio.exitCode != 0)
- {
- cpioDir.Dispose();
- Exit("Failed to extract swu");
- }
-
- return cpioDir;
- }
-}
\ No newline at end of file
diff --git a/csharp/app/VenusFirmwareCiDaemon/src/Device.cs b/csharp/app/VenusFirmwareCiDaemon/src/Device.cs
deleted file mode 100644
index 5f3aeeb23..000000000
--- a/csharp/app/VenusFirmwareCiDaemon/src/Device.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-using System.Diagnostics.CodeAnalysis;
-
-namespace InnovEnergy.Server.FirmwareCiDaemon;
-
-[SuppressMessage("ReSharper", "InconsistentNaming")]
-public enum Device
-{
- BeagleBone,
- BeagleBone2,
- NanoPi,
- Einstein,
- RaspberryPi2
-}
-
-public static class DeviceExtensions
-{
- public static String GetName(this Device device)
- {
- if (device == Device.BeagleBone2)
- device = Device.BeagleBone;
-
- var name = Enum.GetName(device)?.ToLower();
- if (name is null)
- throw new ArgumentException(nameof(device));
-
- return name;
- }
-
- public static String SwuName(this Device device)
- {
- return device switch
- {
- Device.BeagleBone2 => "venus-swu-2",
- _ => "venus-swu"
- };
- }
-
-
- public static String SwuBase(this Device device)
- {
- var deviceName = device.GetName();
- var swuName = device.SwuName();
- return $"{swuName}-{deviceName}";
- }
-
- public static String ShortSwuFileName(this Device device)
- {
- var swuBase = device.SwuBase();
- return $"{swuBase}.swu";
- }
-
- public static String ExtFileName(this Device device)
- {
- var deviceName = device.GetName();
- return $"venus-image-{deviceName}.ext4";
- }
-
- public static String ExtGzFileName(this Device device)
- {
- return device.ExtFileName() + ".gz";
- }
-
- public static String LongSwuFileName(this Device device, String timestamp, String version)
- {
- var swuBase = device.SwuBase();
- return $"{swuBase}-{timestamp}-{version}.swu";
- }
-}
\ No newline at end of file
diff --git a/csharp/app/VenusFirmwareCiDaemon/src/ExitException.cs b/csharp/app/VenusFirmwareCiDaemon/src/ExitException.cs
deleted file mode 100644
index 4921438c3..000000000
--- a/csharp/app/VenusFirmwareCiDaemon/src/ExitException.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-namespace InnovEnergy.Server.FirmwareCiDaemon;
-
-public class ExitException : Exception
-{
- public Int32 ExitCode { get; }
-
- public ExitException(Int32 exitCode = 1): base("")
- {
- ExitCode = exitCode;
- }
-
- public ExitException(String message, Int32 exitCode = 1) : base(message)
- {
- ExitCode = exitCode;
- }
-
- public static void Exit(String msg) => throw new ExitException(msg);
- public static void Exit(Int32 exitCode) => throw new ExitException(exitCode);
-}
\ No newline at end of file
diff --git a/csharp/app/VenusFirmwareCiDaemon/src/Fossil.cs b/csharp/app/VenusFirmwareCiDaemon/src/Fossil.cs
deleted file mode 100644
index e23fe0c2b..000000000
--- a/csharp/app/VenusFirmwareCiDaemon/src/Fossil.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-using CliWrap;
-using InnovEnergy.Lib.Utils;
-using static System.StringSplitOptions;
-using static InnovEnergy.Server.FirmwareCiDaemon.ExitException;
-
-namespace InnovEnergy.Server.FirmwareCiDaemon;
-
-public static class Fossil
-{
- public static String FossilFile { get; set; }
- public static String FossilUser { get; set; }
-
- // TODO: get commit/branch without checkout
-
- public static Commit Checkout(this Branch branch)
- {
- var fossilDir = Open();
- Update(fossilDir, branch, FossilUser);
- return new Commit(fossilDir);
- }
-
- public static CommitInfo GetLatestCommitInfo(this Branch branch)
- {
- using var fossilDir = Open();
- var (hash, comment) = Update(fossilDir, branch, FossilUser);
- return new CommitInfo { Hash = hash, Comment = comment, Branch = branch};
- }
-
- private static Disposable Open()
- {
- var fossilDir = FileSystem.CreateTmpDir();
- var fossilCmd = Cli
- .Wrap("fossil")
- .WithWorkingDirectory(fossilDir);
-
- var open = fossilCmd
- .WithArguments($"open {FossilFile} --empty")
- .ExecuteSync();
-
- if (open.exitCode != 0)
- {
- fossilDir.Dispose();
- Exit("failed to open " + Path.GetFileName(FossilFile) + "\n" + open.stdOut + "\n" + open.stdErr);
- }
-
- return fossilDir.BeforeDisposeDo(Close);
-
- void Close() => fossilCmd.WithArguments("close").ExecuteSync();
- }
-
- public static (String hash, String comment) Update(String fossilDir, Branch branch, String fossilUser)
- {
- var fossil = Cli
- .Wrap("fossil")
- .WithArguments($"update --user {fossilUser} {branch.GetName()}")
- .WithWorkingDirectory(fossilDir)
- .WithValidation(CommandResultValidation.None)
- .ExecuteSync();
-
- if (fossil.exitCode != 0)
- Exit($"failed to update!\n{fossil.stdOut}");
-
- var fossilOutLines = fossil.stdOut.SplitLines();
-
- const String checkoutPrefix = "updated-to:";
- const String commentPrefix = "comment:";
-
- var hash = fossilOutLines
- .Single(l => l.StartsWith(checkoutPrefix))
- .Split(" ", RemoveEmptyEntries)
- .ElementAt(1);
-
- var comment = fossilOutLines
- .Single(l => l.StartsWith(commentPrefix))
- .Substring(commentPrefix.Length)
- .SkipWhile(c => c == ' ')
- .TakeWhile(c => c != '(') // there is a (user: ig) at the end, stops at the first (, but whatever
- .Apply(String.Concat)
- .Trim();
-
- return (hash, comment);
- }
-}
\ No newline at end of file
diff --git a/csharp/app/VenusFirmwareCiDaemon/src/FwSource.cs b/csharp/app/VenusFirmwareCiDaemon/src/FwSource.cs
deleted file mode 100644
index a3007b629..000000000
--- a/csharp/app/VenusFirmwareCiDaemon/src/FwSource.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using InnovEnergy.Lib.Utils;
-
-namespace InnovEnergy.Server.FirmwareCiDaemon;
-
-public enum FwSource
-{
- InnovEnergy,
- Victron
-}
-
-public static class FwSourceExtensions
-{
- public static String GetLatestSwuPath(this FwSource source, Channel channel, Device device)
- {
- var path = source.GetDirectory(channel, device);
- var file = device.ShortSwuFileName();
-
- return path.AppendPath(file);
- }
-
- public static String GetDirectory(this FwSource source, Channel channel, Device device)
- {
- var basePath = source == FwSource.InnovEnergy
- ? Program.IeBasePath
- : Program.VeBasePath;
-
- return basePath
- .AppendPath("venus")
- .AppendPath(channel.GetName())
- .AppendPath("images")
- .AppendPath(device.GetName()) + '/';
- }
-}
\ No newline at end of file
diff --git a/csharp/app/VenusFirmwareCiDaemon/src/Logger.cs b/csharp/app/VenusFirmwareCiDaemon/src/Logger.cs
deleted file mode 100644
index 3e5deaab6..000000000
--- a/csharp/app/VenusFirmwareCiDaemon/src/Logger.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace InnovEnergy.Server.FirmwareCiDaemon;
-
-public static class Logger
-{
- public static void Log(String s = "")
- {
- Console.WriteLine($"{DateTime.Now:yyyy'-'MM'-'dd' 'HH':'mm':'ss} {s}");
- }
-}
\ No newline at end of file
diff --git a/csharp/app/VenusFirmwareCiDaemon/src/Program.cs b/csharp/app/VenusFirmwareCiDaemon/src/Program.cs
deleted file mode 100644
index 4d2803902..000000000
--- a/csharp/app/VenusFirmwareCiDaemon/src/Program.cs
+++ /dev/null
@@ -1,193 +0,0 @@
-using System.Reactive.Concurrency;
-using System.Reactive.Linq;
-using System.Reactive.Subjects;
-using System.Text.RegularExpressions;
-using CliWrap;
-using InnovEnergy.Lib.Utils;
-using static InnovEnergy.Server.FirmwareCiDaemon.Logger;
-using static InnovEnergy.Server.FirmwareCiDaemon.ExitException;
-
-namespace InnovEnergy.Server.FirmwareCiDaemon;
-// dotnet publish FirmwareCiDaemon.csproj -c Release -r linux-x64 -p:PublishSingleFile=true --self-contained true && scp ./bin/Release/netcoreapp5.0/linux-x64/publish/FirmwareCiDaemon ig@salidomo.innovenergy.ch:/home/ig/firmware
-
-public static class Program
-{
-
- // use the following scheduler to run everything on a single thread
- // Fossil cannot deal with the async introduced by multiple threads/tasks
- private static readonly IScheduler Scheduler = new EventLoopScheduler();//NewThreadScheduler();
-
- private static readonly IEnumerable SupportedDevices = Enum.GetValues();
- private static readonly IEnumerable Branches = Enum.GetValues();
-
- public static String IeBasePath { get; set; }
- public static String VeBasePath => "https://updates.victronenergy.com/feeds/";
-
- public static void Main(String[] args)
- {
- try
- {
- Run(args);
- }
- catch (Exception e)
- {
- PrintExceptionAndExit(e);
- }
- //Environment.Exit(0);
- }
-
- // runcmd: program
-
- private static void Run(String[] args)
- {
- if (!IsRoot) Exit("This program must be run as root");
-
- Fossil.FossilFile = ParseFossilFileArg(args); // TODO: get rid of global vars?
- Fossil.FossilUser = ParseFossilUserArg(args);
- IeBasePath = ParseIePublishDirArg(args);
-
- var veVersions = SupportedDevices.Select(ObserveVeVersion).ToList();
- var branches = Branches.Select(ObserveFossilBranch).ToList();
-
- var buildInfos = from veVersion in veVersions
- from branch in branches
- select Observable.CombineLatest(branch, veVersion, Build.Prepare);
-
- buildInfos.Merge()
- .ObserveOn(Scheduler) // fossil is not thread safe!
- .Subscribe(build => build.Execute(), PrintExceptionAndExit);
-
- foreach (var veVersion in veVersions)
- veVersion.Connect();
-
- foreach (var branch in branches)
- branch.Connect();
-
- while (true) Console.ReadLine();
-
- // ReSharper disable once FunctionNeverReturns
- }
-
- private static IConnectableObservable ObserveFossilBranch(Branch branch)
- {
- return Observable
- .Interval(TimeSpan.FromMinutes(1))
- .StartWith(0)
- .ObserveOn(Scheduler) // fossil is not thread safe!
- .Select(_ => Fossil.GetLatestCommitInfo(branch))
- .DistinctUntilChanged()
- .Do(c => Log($"Found new commit '{c.Comment}' on branch {c.Branch} ({c.Hash[..6]})"))
- .Publish();
- }
-
- private static IConnectableObservable<(Device device, String veVersion)> ObserveVeVersion(Device device)
- {
- return Observable
- .Interval(TimeSpan.FromHours(1))
- .StartWith(0)
- .Select(_ => device)
- .Select(GetLatestVictronVersion)
- .DistinctUntilChanged()
- .Select(veVersion => (device, veVersion))
- .Do(vd => Log($"Found new Victron version '{vd.veVersion}' for {vd.device}"))
- .Publish();
- }
-
- public static String GetLatestVictronVersion(Device device)
- {
- var url = FwSource.Victron.GetDirectory(Channel.Release, device);
-
- var curl = Cli
- .Wrap("curl")
- .WithArguments(url)
- .ExecuteSync()
- .stdOut;
-
- var deviceName = device.GetName();
- var swuName = device.SwuName();
-
- const String timeStampPattern = "[0-9]{14}";
- const String releasePattern = @"v[0-9]+\.[0-9]+";
- const String extension = ".swu";
- const String extensionPattern = @"\" + extension; // escape .
-
- var rxVersion = new Regex($"{swuName}-{deviceName}-{timeStampPattern}-{releasePattern}{extensionPattern}");
-
- return rxVersion
- .Matches(curl)
- .Select(m => m.Value)
- .OrderBy(m => m)
- .Last()
- .Split("-")
- .Last()
- .RemoveSuffix(extension);
- }
-
- private static Boolean IsRoot
- {
- get
- {
- var (exitCode, stdOut, stdErr) = Cli
- .Wrap("id")
- .WithArguments("-u")
- .ExecuteSync();
-
- return exitCode == 0 &&
- stdOut.Trim() == "0" &&
- String.IsNullOrWhiteSpace(stdErr);
- }
- }
-
-
- private static String ParseFossilFileArg(IReadOnlyList args)
- {
- if (args.Count < 1)
- Exit("Missing argument ");
-
- var fossilFile = Path.GetFullPath(args[0]);
-
- if (!FileSystem.Local.FileExists(fossilFile))
- Exit($"Cannot find fossil file {fossilFile}");
-
- return fossilFile;
- }
-
- private static String ParseIePublishDirArg(IReadOnlyList args)
- {
- if (args.Count < 2)
- Exit("Missing argument ");
-
- var iePublishDir = Path.GetFullPath(args[1]);
-
- if (!FileSystem.Local.DirectoryExists(iePublishDir))
- Exit($"Cannot find directory {iePublishDir}");
-
- return iePublishDir;
- }
-
- private static String ParseFossilUserArg(IReadOnlyList args)
- {
- if (args.Count < 3)
- Exit("Missing argument ");
-
- return args[2];
- }
-
- private static void PrintExceptionAndExit(Exception e)
- {
- if (!String.IsNullOrWhiteSpace(e.Message))
- {
- Console.WriteLine();
-
- var color = Console.ForegroundColor;
- Console.ForegroundColor = ConsoleColor.Red;
- Log(e.Message);
- Console.ForegroundColor = color;
- }
-
- if (!String.IsNullOrWhiteSpace(e.StackTrace))
- Log(e.StackTrace);
-
- Environment.Exit(1);
- }
-}
\ No newline at end of file
diff --git a/csharp/app/VenusFirmwareCiDaemon/src/Zip.cs b/csharp/app/VenusFirmwareCiDaemon/src/Zip.cs
deleted file mode 100644
index 49f3f8acc..000000000
--- a/csharp/app/VenusFirmwareCiDaemon/src/Zip.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-using CliWrap;
-using static InnovEnergy.Server.FirmwareCiDaemon.Logger;
-using static InnovEnergy.Server.FirmwareCiDaemon.ExitException;
-
-namespace InnovEnergy.Server.FirmwareCiDaemon;
-
-public static class Zip
-{
- public static void RemoveFromZip(this String zipFilePath, String zipInternalPathGlob)
- {
- var zip = Cli
- .Wrap("zip")
- .WithArguments($"-q -d {zipFilePath} {zipInternalPathGlob}")
- .ExecuteSync();
-
- if (zip.exitCode != 0)
- Log($"Warning: failed to remove {zipInternalPathGlob} from {zipFilePath}");
- }
-
- public static void AddToZip(this String zipFilePath, String filePath)
- {
- var zip = Cli
- .Wrap("zip")
- .WithArguments($"-q -j {zipFilePath} {filePath}")
- .ExecuteSync();
-
- if (zip.exitCode != 0)
- Exit($"failed to add {filePath} to {zipFilePath}");
- }
-
- public static void GZip(this String sourceFile, String targetGzFile)
- {
- // TODO: datetime log
-
- Log($"compressing {Path.GetFileName(sourceFile)}");
-
- var gzip = Cli
- .Wrap("gzip")
- .WithArguments($"-c {sourceFile}")
- .PipeToFile(targetGzFile);
-
- if (gzip.exitCode != 0)
- Exit($"Failed to gzip {sourceFile}");
- }
-}
\ No newline at end of file