diff --git a/csharp/App/Backend/Controller.cs b/csharp/App/Backend/Controller.cs index 188bfcc92..bbaa7f3ca 100644 --- a/csharp/App/Backend/Controller.cs +++ b/csharp/App/Backend/Controller.cs @@ -267,7 +267,7 @@ public class Controller : ControllerBase if (! await session.Create(installation)) return Unauthorized(); - return installation.FillOrderNumbers().HideParentIfUserHasNoAccessToParent(session!.User); + return installation; } [HttpPost(nameof(CreateFolder))] diff --git a/csharp/App/Backend/Properties/launchSettings.json b/csharp/App/Backend/Properties/launchSettings.json index dc2ac027a..d04542990 100644 --- a/csharp/App/Backend/Properties/launchSettings.json +++ b/csharp/App/Backend/Properties/launchSettings.json @@ -7,7 +7,7 @@ "dotnetRunMessages": true, "launchUrl": "swagger", - "applicationUrl": "https://localhost:7087;http://localhost:5031", + "applicationUrl": "https://localhost:8000", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/csharp/App/SaliMax/Doc/AllStates.graphml b/csharp/App/SaliMax/Doc/AllStates.graphml index 23d73c65a..2888ad499 100644 --- a/csharp/App/SaliMax/Doc/AllStates.graphml +++ b/csharp/App/SaliMax/Doc/AllStates.graphml @@ -137,7 +137,7 @@ K3 ✓ - + 5 @@ -154,7 +154,7 @@ K3 ✓ - + 7 @@ -172,7 +172,7 @@ K3 ✓ - + 11 @@ -190,11 +190,11 @@ K3 ✘ - + 15 - K1 ✓ + K1 ✓ K2 ✓ K3 ✓ @@ -207,7 +207,7 @@ K3 ✓ - + 21 @@ -224,7 +224,7 @@ K3 ✓ - + 17 @@ -242,7 +242,7 @@ K3 ✘ - + 25 @@ -260,7 +260,7 @@ K3 ✘ - + 27 @@ -278,7 +278,7 @@ K3 ✘ - + 31 @@ -414,7 +414,7 @@ K3 ✓ - + 16 @@ -448,7 +448,7 @@ K3 ✓ - + 18 @@ -465,7 +465,7 @@ K3 ✘ - + 2 @@ -482,7 +482,7 @@ K3 ✘ - + 10 @@ -499,7 +499,7 @@ K3 ✘ - + 12 @@ -516,7 +516,7 @@ K3 ✓ - + 14 @@ -533,7 +533,7 @@ K3 ✓ - + 26 @@ -550,7 +550,7 @@ K3 ✘ - + 30 @@ -582,8 +582,8 @@ Inverters - switch to -grid tie + switch to +grid tie @@ -641,10 +641,13 @@ Inverters - + + + + - open K2 + open K2 @@ -656,7 +659,7 @@ Inverters - open K2 + open K2 @@ -665,11 +668,14 @@ Inverters - + + + + - turn off -inverter + turn off +inverter @@ -681,7 +687,7 @@ inverter - turn off + turn off inverters @@ -694,7 +700,7 @@ inverters - turn off + turn off inverters @@ -707,7 +713,7 @@ inverters - turn off + turn off inverters @@ -717,11 +723,14 @@ inverters - + + + + - turn off -inverters + turn off +inverters @@ -743,8 +752,8 @@ inverters - turn off -Inverters + turn off +Inverters @@ -817,7 +826,7 @@ Inverters - turn off + turn off inverters @@ -827,10 +836,13 @@ inverters - + + + + - open K2 + open K2 @@ -839,10 +851,13 @@ inverters - + + + + - open K2 + open K2 @@ -854,7 +869,7 @@ inverters - K3 opens + K3 opens @@ -866,7 +881,7 @@ inverters - open K2 + open K2 @@ -878,7 +893,7 @@ inverters - turn off + turn off inverters @@ -891,7 +906,7 @@ inverters - turn off + turn off inverters @@ -914,7 +929,7 @@ inverters - + K1 opens @@ -925,11 +940,14 @@ inverters - + + + + - turn off -inverters + turn off +inverters @@ -938,10 +956,13 @@ inverters - + + + + - K3's open + K3's open @@ -949,10 +970,13 @@ inverters - + + + + - K3's open + K3's open diff --git a/csharp/App/SaliMax/HostList.sh b/csharp/App/SaliMax/HostList.sh index 2d493c965..7ccce677d 100755 --- a/csharp/App/SaliMax/HostList.sh +++ b/csharp/App/SaliMax/HostList.sh @@ -3,4 +3,6 @@ Prototype ie-entwicklung@10.2.3.115 Salimax001 ie-entwicklung@10.2.3.104 Salimax002 ie-entwicklung@10.2.4.29 Salimax003 ie-entwicklung@10.2.4.33 -Salimax004 ie-entwicklung@10.2.4.32 \ No newline at end of file +Salimax004 ie-entwicklung@10.2.4.32 +Salimax005 ie-entwicklung@10.2.4.36 +Salimax006 ie-entwicklung@10.2.4.35 \ No newline at end of file diff --git a/csharp/App/SaliMax/deploy.sh b/csharp/App/SaliMax/deploy.sh index b55e6e141..0b31506d6 100755 --- a/csharp/App/SaliMax/deploy.sh +++ b/csharp/App/SaliMax/deploy.sh @@ -18,5 +18,5 @@ echo -e "\n============================ Deploy ============================\n" rsync -v \ ./bin/Release/$dotnet_version/linux-x64/publish/* \ - $username@$salimax_ip:~/salimax + $username@"$salimax_ip":~/salimax diff --git a/csharp/App/SaliMax/src/Ess/Controller.cs b/csharp/App/SaliMax/src/Ess/Controller.cs index 7d6601450..368b86850 100644 --- a/csharp/App/SaliMax/src/Ess/Controller.cs +++ b/csharp/App/SaliMax/src/Ess/Controller.cs @@ -2,6 +2,7 @@ using InnovEnergy.Lib.Devices.Battery48TL.DataTypes; using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc; using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; using InnovEnergy.Lib.Time.Unix; +using InnovEnergy.Lib.Units; using InnovEnergy.Lib.Utils; namespace InnovEnergy.App.SaliMax.Ess; @@ -9,12 +10,13 @@ namespace InnovEnergy.App.SaliMax.Ess; public static class Controller { private static readonly UnixTimeSpan MaxTimeWithoutEoc = UnixTimeSpan.FromDays(7); // TODO: move to config + private static readonly Double BatteryHeatingPower = 200.0; // TODO: move to config public static EssMode SelectControlMode(this StatusRecord s) { //return EssMode.OptimizeSelfConsumption; - return s.StateMachine.State != 16 ? EssMode.Off + return s.StateMachine.State != 23 ? EssMode.Off : s.MustHeatBatteries() ? EssMode.HeatBatteries : s.MustDoCalibrationCharge() ? EssMode.CalibrationCharge : s.MustReachMinSoc() ? EssMode.ReachMinSoc @@ -25,9 +27,7 @@ public static class Controller public static EssControl ControlEss(this StatusRecord s) { - var mode = s.SelectControlMode(); - - mode.WriteLine(); + var mode = s.SelectControlMode().WriteLine(); if (mode is EssMode.Off or EssMode.NoGridMeter) return EssControl.Default; @@ -85,7 +85,7 @@ public static class Controller // find out if we reach the lower or upper Dc limit by comparing the current Dc voltage to the reference voltage - return s.AcDc.Dc.Voltage > s.Config.ReferenceDcBusVoltage + return s.AcDc.Dc.Voltage > s.Config.ReferenceDcLinkVoltageFromAcDc ? control with { PowerCorrection = clampedPowerDelta.ClampMax(-correction), LimitedBy = EssLimit.ChargeLimitedByMaxDcBusVoltage } : control with { PowerCorrection = clampedPowerDelta.ClampMin(correction), LimitedBy = EssLimit.DischargeLimitedByMinDcBusVoltage }; } @@ -122,7 +122,7 @@ public static class Controller private static Double ComputePowerDelta(this StatusRecord s, EssMode mode) { var chargePower = s.AcDc.Devices.Sum(d => d.Status.Nominal.Power.Value); - + return mode switch { EssMode.HeatBatteries => s.ControlInverterPower(chargePower), @@ -153,7 +153,19 @@ public static class Controller private static Double MaxBatteryChargePower(this StatusRecord s) { - return s.Battery.Devices.Sum(b => b.MaxChargePower); + // This introduce a limit when we don't have communication with batteries + // Otherwise the limit will be 0 and the batteries will be not heated + + var maxChargePower = s.Config.Devices.BatteryNodes.Length * BatteryHeatingPower; + + if (s.Battery.Devices.Count != 0) + { + maxChargePower = s.Battery.Devices.Sum(b => b.MaxChargePower); + } + + maxChargePower.W().ToDisplayString().WriteLine(" Max Charge Power"); + + return maxChargePower; } private static Double CurrentPowerSetPoint(this StatusRecord s) diff --git a/csharp/App/SaliMax/src/Flow.cs b/csharp/App/SaliMax/src/Flow.cs index 0d173bc02..763c7cee2 100644 --- a/csharp/App/SaliMax/src/Flow.cs +++ b/csharp/App/SaliMax/src/Flow.cs @@ -12,7 +12,9 @@ public static class Flow private static readonly String DownArrowChar = "V"; private static readonly String UpArrowChar = "^"; - public static TextBlock Horizontal(Unit amount, Int32 width = 10) + public static TextBlock Horizontal(Unit amount) => Horizontal(amount, 10); + + public static TextBlock Horizontal(Unit amount, Int32 width) { var label = amount.ToDisplayString(); var arrowChar = amount.Value < 0 ? LeftArrowChar : RightArrowChar; @@ -21,19 +23,21 @@ public static class Flow // note : appending "fake label" below to make it vertically symmetric return TextBlock.AlignCenterHorizontal(label, arrow, ""); } - + + public static TextBlock Vertical(Unit amount) => Vertical(amount, 4); + [SuppressMessage("ReSharper", "PossibleMultipleEnumeration")] [SuppressMessage("ReSharper", "CoVariantArrayConversion")] - public static TextBlock Vertical(Unit amount, Int32 height = 4) + public static TextBlock Vertical(Unit amount, Int32 height) { var label = amount.ToDisplayString(); var arrowChar = amount.Value < 0 ? UpArrowChar : DownArrowChar; var halfArrow = Enumerable.Repeat(arrowChar, height/2); var lines = halfArrow - .Append(label) - .Concat(halfArrow) - .ToArray(height / 2 * 2 + 1); + .Append(label) + .Concat(halfArrow) + .ToArray(height / 2 * 2 + 1); return TextBlock.AlignCenterHorizontal(lines); } diff --git a/csharp/App/SaliMax/src/Logfile.cs b/csharp/App/SaliMax/src/Logfile.cs index 6465109df..d31ebd8c8 100644 --- a/csharp/App/SaliMax/src/Logfile.cs +++ b/csharp/App/SaliMax/src/Logfile.cs @@ -18,15 +18,9 @@ public class CustomLogger : ILogger _CurrentFileSizeBytes = File.Exists(logFilePath) ? new FileInfo(logFilePath).Length : 0; } - public IDisposable? BeginScope(TState state) where TState : notnull - { - throw new NotImplementedException(); - } + public IDisposable? BeginScope(TState state) where TState : notnull => throw new NotImplementedException(); - public Boolean IsEnabled(LogLevel logLevel) - { - return true; // Enable logging for all levels - } + public Boolean IsEnabled(LogLevel logLevel) => true; // Enable logging for all levels public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) { @@ -43,7 +37,7 @@ public class CustomLogger : ILogger File.AppendAllText(_LogFilePath, logMessage + Environment.NewLine); _CurrentFileSizeBytes += logMessage.Length; - Console.WriteLine( logMessage + Environment.NewLine); + Console.WriteLine(logMessage); } private void RotateLogFile() diff --git a/csharp/App/SaliMax/src/Program.cs b/csharp/App/SaliMax/src/Program.cs index d195a75d6..cd91a3eb3 100644 --- a/csharp/App/SaliMax/src/Program.cs +++ b/csharp/App/SaliMax/src/Program.cs @@ -1,4 +1,5 @@ -using System.Runtime.InteropServices; +using System.Reactive.Linq; +using System.Reactive.Threading.Tasks; using Flurl.Http; using InnovEnergy.App.SaliMax.Ess; using InnovEnergy.App.SaliMax.SaliMaxRelays; @@ -13,10 +14,10 @@ using InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes; using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc; using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc; +using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Control; using InnovEnergy.Lib.Protocols.Modbus.Channels; using InnovEnergy.Lib.Time.Unix; using InnovEnergy.Lib.Units; -using InnovEnergy.Lib.Units.Power; using InnovEnergy.Lib.Utils; using static InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes.SystemConfig; using AcPower = InnovEnergy.Lib.Units.Composite.AcPower; @@ -28,10 +29,7 @@ namespace InnovEnergy.App.SaliMax; internal static class Program { - [DllImport("libsystemd.so.0")] - private static extern Int32 sd_notify(Int32 unsetEnvironment, String state); - - private const UInt32 UpdateIntervalSeconds = 2; + private static readonly UnixTimeSpan UpdateInterval = UnixTimeSpan.FromSeconds(2); private static readonly IReadOnlyList BatteryNodes; @@ -59,7 +57,7 @@ internal static class Program BatteryNodes = config .Devices .BatteryNodes - .Select(n=>n.ConvertTo()) + .Select(n => n.ConvertTo()) .ToArray(config.Devices.BatteryNodes.Length); } @@ -82,8 +80,7 @@ internal static class Program { "Starting SaliMax".LogInfo(); - // Send the initial "service started" message to systemd - var sdNotifyReturn = sd_notify(0, "READY=1"); + Watchdog.Ready(); var battery48TlDevices = BatteryNodes .Select(n => new Battery48TlDevice(BatteriesChannel, n)) @@ -99,25 +96,12 @@ internal static class Program StatusRecord ReadStatus() { - "Reading AcDC".LogInfo(); - var acDc = acDcDevices.Read(); - - "Reading dcDc".LogInfo(); - var dcDc = dcDcDevices.Read(); - - "Reading battery".LogInfo(); var battery = batteryDevices.Read(); - - "Reading relays".LogInfo(); + var acDc = acDcDevices.Read(); + var dcDc = dcDcDevices.Read(); var relays = saliMaxRelaysDevice.Read(); - - "Reading loadOnAcIsland".LogInfo(); var loadOnAcIsland = acIslandLoadMeter.Read(); - - "Reading gridMeter".LogInfo(); var gridMeter = gridMeterDevice.Read(); - - "Reading pvOnDc".LogInfo(); var pvOnDc = amptDevice.Read(); var pvOnAcGrid = AcPowerDevice.Null; @@ -144,7 +128,6 @@ internal static class Program var loadOnDc = new DcPowerDevice { Power = dcPower} ; - return new StatusRecord { AcDc = acDc ?? AcDcDevicesRecord.Null, @@ -176,223 +159,69 @@ internal static class Program acDcDevices.Write(r.AcDc); dcDcDevices.Write(r.DcDc); } - - const Int32 delayTime = 10; - Console.WriteLine("press ctrl-C to stop"); + Console.WriteLine("press ctrl-c to stop"); + while (true) { - sd_notify(0, "WATCHDOG=1"); - + await Observable + .Interval(UpdateInterval.ToTimeSpan()) + .Select(_ => RunIteration()) + .SelectMany(r => UploadCsv(r, UnixTime.Now.RoundTo(UpdateInterval))) + .SelectError() + .ToTask(); + } + + + // var iterations = from _ in Observable.Interval(UpdateInterval.ToTimeSpan()) + // let t = UnixTime.Now.RoundTo(UpdateInterval) + // let record = RunIteration() + // from uploaded in UploadCsv(record, t) + // select uploaded; + // + // using var running = iterations.Subscribe(); + + + StatusRecord RunIteration() + { + Watchdog.Alive(); + var t = UnixTime.Now; - while (t.Ticks % UpdateIntervalSeconds != 0) - { - await Task.Delay(delayTime); - t = UnixTime.Now; - } - - - var record = ReadStatus(); - - if (record.Relays is not null) - record.Relays.ToCsv().LogInfo(); - - record.ControlConstants(); + record.ControlConstants(); record.ControlSystemState(); - (t + "\n").LogInfo(); $"{record.StateMachine.State}: {record.StateMachine.Message}".LogInfo(); - $"Batteries SOC: {record.Battery.Soc}".LogInfo(); + var essControl = record.ControlEss().LogInfo(); record.EssControl = essControl; record.AcDc.SystemControl.ApplyAcDcDefaultSettings(); record.DcDc.SystemControl.ApplyDcDcDefaultSettings(); - + DistributePower(record, essControl); WriteControl(record); - - PrintTopology(record); - await UploadCsv(record, t); + Topology.From(record).WriteLine(); + + //record.ToCsv().WriteLine(); + + //await UploadCsv(record, t); record.Config.Save(); - + "===========================================".LogInfo(); + + return record; } + // ReSharper disable once FunctionNeverReturns } - private static void PrintTopology(StatusRecord s) - { - // Power Measurement Values - var gridPower = s.GridMeter is not null ? s.GridMeter!.Ac.Power.Active : 0; - var inverterPower = s.AcDc.Ac.Power.Active; - var islandLoadPower = s.LoadOnAcIsland is not null ? s.LoadOnAcIsland.Ac.Power.Active : 0; - var dcBatteryPower = s.DcDc.Dc.Battery.Power; - var dcdcPower = s.DcDc.Dc.Link.Power; - var pvOnDcPower = s.PvOnDc.Dc!.Power.Value; - - // Power Calculated Values - var islandToGridBusPower = inverterPower + islandLoadPower; - var gridLoadPower = s.LoadOnAcGrid is null ? 0: s.LoadOnAcGrid.Power.Active; - - TextBlock gridBusColumn; - TextBlock gridBox; - TextBlock totalBoxes; - - - if (s.GridMeter is not null) - { - var gridPowerByPhase = TextBlock.AlignLeft(s.GridMeter.Ac.L1.Power.Active.ToDisplayString(), - s.GridMeter.Ac.L2.Power.Active.ToDisplayString(), - s.GridMeter.Ac.L3.Power.Active.ToDisplayString()); - - var gridVoltageByPhase = TextBlock.AlignLeft(s.GridMeter.Ac.L1.Voltage.ToDisplayString(), - s.GridMeter.Ac.L2.Voltage.ToDisplayString(), - s.GridMeter.Ac.L3.Voltage.ToDisplayString()); - - gridBusColumn = ColumnBox("Pv", "Grid Bus", "Load" , gridVoltageByPhase , gridLoadPower); - gridBox = TextBlock.AlignLeft(gridPowerByPhase).TitleBox("Grid"); - - } - else - { - gridBusColumn = TextBlock.Spacer(0); - gridBox = TextBlock.Spacer(0); - } - - - - var inverterPowerByPhase = TextBlock.AlignLeft(s.AcDc.Ac.L1.Power.Active.ToDisplayString(), - s.AcDc.Ac.L2.Power.Active.ToDisplayString(), - s.AcDc.Ac.L3.Power.Active.ToDisplayString()); - - // ReSharper disable once CoVariantArrayConversion - var inverterPowerByAcDc = TextBlock.AlignLeft(s.AcDc.Devices - .Select(s1 => s1.Status.Ac.Power) - .ToArray()); - - var dcLinkVoltage = TextBlock.AlignCenterHorizontal("", - s.DcDc.Dc.Link.Voltage.ToDisplayString(), - ""); - - var dc48Voltage = s.DcDc.Dc.Battery.Voltage.ToDisplayString(); - var batteryVoltage = s.Battery.Dc.Voltage.Value.RoundToSignificantDigits(3); - var batterySoc = s.Battery.Devices.Any()? s.Battery.Devices.Average(b=>b.Soc).Percent().ToDisplayString() : "0"; - var batteryCurrent = s.Battery.Dc.Current.ToDisplayString(); - var batteryTemp = s.Battery.Temperature.ToDisplayString(); - var batteryHeatingCurrent = s.Battery.HeatingCurrent.ToDisplayString(); - var anyBatteryAlarm = s.Battery.Alarms.Any(); - var anyBatteryWarning = s.Battery.Warnings.Any(); - - var islandBusColumn = ColumnBox("Pv", "Island Bus", "Load" , inverterPowerByPhase, islandLoadPower); - var dcBusColumn = ColumnBox("Pv", "Dc Bus", "Load" , dcLinkVoltage, 0, pvOnDcPower); - var gridBusFlow = Flow.Horizontal(gridPower); - var flowGridBusToIslandBus = Flow.Horizontal((ActivePower)islandToGridBusPower); - var flowIslandBusToInverter = Flow.Horizontal(inverterPower); - var flowInverterToDcBus = Flow.Horizontal(inverterPower); - var flowDcBusToDcDc = Flow.Horizontal(dcdcPower); - var flowDcDcToBattery = Flow.Horizontal(dcBatteryPower); - - var inverterBox = TextBlock.AlignLeft(inverterPowerByAcDc).TitleBox("AC/DC"); - var dcDcBox = TextBlock.AlignLeft(dc48Voltage).TitleBox("DC/DC"); - var batteryAvgBox = TextBlock.AlignLeft(batteryVoltage, - batterySoc, - batteryCurrent, - batteryTemp, - batteryHeatingCurrent, - anyBatteryWarning, - anyBatteryAlarm) - .TitleBox("Battery"); - - - //////////////////// Batteries ///////////////////////// - - IReadOnlyList batteryBoxes = s.Battery - .Devices - .Select(CreateIndividualBattery) - .ToArray(s.Battery.Devices.Count); - - var individualBatteries = batteryBoxes.Any() - ? TextBlock.AlignLeft(batteryBoxes) - : TextBlock.Spacer(1); - - if (s.GridMeter is not null) - { - totalBoxes = TextBlock.AlignCenterVertical(gridBox, - gridBusFlow, - gridBusColumn, - flowGridBusToIslandBus, - islandBusColumn, - flowIslandBusToInverter, - inverterBox, - flowInverterToDcBus, - dcBusColumn, - flowDcBusToDcDc, - dcDcBox, - flowDcDcToBattery, - batteryAvgBox, - individualBatteries); - } - else - { - totalBoxes = TextBlock.AlignCenterVertical( - islandBusColumn, - flowIslandBusToInverter, - inverterBox, - flowInverterToDcBus, - dcBusColumn, - flowDcBusToDcDc, - dcDcBox, - flowDcDcToBattery, - batteryAvgBox, - individualBatteries); - } - - totalBoxes.WriteLine(); - } - - private static TextBlock CreateIndividualBattery(Battery48TlRecord battery, Int32 i) - { - var batteryWarnings = battery.Warnings.Any(); - var batteryAlarms = battery.Alarms.Any(); - - var content = TextBlock.AlignLeft(battery.Dc.Voltage.ToDisplayString(), - battery.Soc.ToDisplayString(), - battery.Dc.Current.ToDisplayString(), - battery.Temperatures.Cells.Average.ToDisplayString(), - // battery.BusCurrent.ToDisplayString(), - battery.HeatingCurrent.ToDisplayString(), - batteryWarnings, - batteryAlarms); - - var box = content.TitleBox($"Battery {i + 1}"); - - var flow = Flow.Horizontal(battery.Dc.Power); - - return TextBlock.AlignCenterVertical(flow, box); - } - - private static TextBlock ColumnBox(String pvTitle, String busTitle, String loadTitle, TextBlock dataBox, ActivePower loadPower) - { - return ColumnBox(pvTitle, busTitle, loadTitle, dataBox, loadPower, 0); - } - - private static TextBlock ColumnBox(String pvTitle, String busTitle, String loadTitle, TextBlock dataBox, ActivePower loadPower, ActivePower pvPower) - { - var pvBox = TextBlock.FromString(pvTitle).Box(); - var pvToBus = Flow.Vertical(pvPower); - var busBox = TextBlock.AlignLeft(dataBox).TitleBox(busTitle); - var busToLoad = Flow.Vertical(loadPower); - var loadBox = TextBlock.FromString(loadTitle).Box(); - - return TextBlock.AlignCenterHorizontal(pvBox, pvToBus, busBox, busToLoad, loadBox); - } + private static async Task ResultOrNull(this Task task) { @@ -407,14 +236,20 @@ internal static class Program var inverters = r.AcDc.Devices; var dcDevices = r.DcDc.Devices; - inverters.ForEach(d => d.Control.Dc.MaxVoltage = r.Config.MaxDcBusVoltage); - inverters.ForEach(d => d.Control.Dc.MinVoltage = r.Config.MinDcBusVoltage); - inverters.ForEach(d => d.Control.Dc.ReferenceVoltage = r.Config.ReferenceDcBusVoltage); + inverters.ForEach(d => d.Control.Dc.MaxVoltage = r.Config.MaxDcLinkVoltageFromAcDc); + inverters.ForEach(d => d.Control.Dc.MinVoltage = r.Config.MinDcLinkVoltageFromAcDc); + inverters.ForEach(d => d.Control.Dc.ReferenceVoltage = r.Config.ReferenceDcLinkVoltageFromAcDc); + inverters.ForEach(d => d.Control.Dc.PrechargeConfig = DcPrechargeConfig.PrechargeDcWithInternal); + + dcDevices.ForEach(d => d.Control.DroopControl.UpperVoltage = r.Config.UpperDcLinkVoltageFromDc); + dcDevices.ForEach(d => d.Control.DroopControl.LowerVoltage = r.Config.LowerDcLinkVoltageFromDc); + dcDevices.ForEach(d => d.Control.DroopControl.ReferenceVoltage = r.Config.ReferenceDcLinkVoltageFromDc); + dcDevices.ForEach(d => d.Control.CurrentControl.MaxBatteryChargingCurrent = r.Config.MaxBatteryChargingCurrent); + dcDevices.ForEach(d => d.Control.CurrentControl.MaxBatteryDischargingCurrent = r.Config.MaxBatteryDischargingCurrent); + dcDevices.ForEach(d => d.Control.VoltageLimits.MaxBatteryVoltage = r.Config.MaxChargeBatteryVoltage); + dcDevices.ForEach(d => d.Control.VoltageLimits.MinBatteryVoltage = r.Config.MinDischargeBatteryVoltage); + dcDevices.ForEach(d => d.Control.ControlMode = DcControlMode.VoltageDroop); - // dcDevices.ForEach(d => d.Control. Dc.MaxVoltage = r.Config.MaxDcBusVoltage); - // dcDevices.ForEach(d => d.Control. Dc.MinVoltage = r.Config.MinDcBusVoltage); - // dcDevices.ForEach(d => d.Control. Dc.ReferenceVoltage = r.Config.ReferenceDcBusVoltage); - r.DcDc.ResetAlarms(); r.AcDc.ResetAlarms(); } @@ -483,11 +318,11 @@ internal static class Program sc.ResetAlarmsAndWarnings = true; } - private static async Task UploadCsv(StatusRecord status, UnixTime timeStamp) + private static async Task UploadCsv(StatusRecord status, UnixTime timeStamp) { var s3Config = status.Config.S3; if (s3Config is null) - return; + return false; var csv = status.ToCsv(); var s3Path = timeStamp + ".csv"; @@ -500,6 +335,7 @@ internal static class Program var error = response.GetStringAsync(); Console.WriteLine(error); } + + return true; } -} - +} \ No newline at end of file diff --git a/csharp/App/SaliMax/src/System/Controller.cs b/csharp/App/SaliMax/src/System/Controller.cs index 7e20ca8eb..b4559c1bd 100644 --- a/csharp/App/SaliMax/src/System/Controller.cs +++ b/csharp/App/SaliMax/src/System/Controller.cs @@ -1,6 +1,5 @@ using InnovEnergy.App.SaliMax.Ess; using InnovEnergy.App.SaliMax.SaliMaxRelays; -using InnovEnergy.Lib.Devices.Battery48TL; using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc; using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc; using static InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes.GridType; @@ -21,14 +20,18 @@ public static class Controller if (acDcs.NotAvailable()) return 102; - var k4 = acDcs.AllDisabled() ? 0 - : acDcs.AllGridTied() ? 1 - : acDcs.AllIsland() ? 2 + + var k4 = acDcs.AllGridTied() ? 0 + : acDcs.AllIsland() ? 1 : 4; - if (k4 == 4) - return 103; //Message = "Panic: ACDCs have unequal grid types", + var k5 = acDcs.AllDisabled() ? 0 + : acDcs.AllEnabled() ? 1 + : 4; + if (k4 == 4 || k5 == 4) + return 103; //Message = "Panic: ACDCs have unequal grid types or power stage", + var nInverters = r.AcDc.Devices.Count; var k1 = relays.K1GridBusIsConnectedToGrid ? 1 : 0; @@ -36,32 +39,34 @@ public static class Controller var k3 = relays.K3InverterIsConnectedToIslandBus.Take(nInverters).Any(c => c) ? 1 : 0; // states as defined in states excel sheet - return 1 - + 1*k1 - + 2*k2 - + 4*k3 - + 8*k4; + return 1 * k1 + + 2 * k2 + + 4 * k3 + + 8 * k4 + + 16 * k5; } public static Boolean ControlSystemState(this StatusRecord s) { s.StateMachine.State = s.GetSystemState(); - + return s.StateMachine.State switch { + 0 => State0(s), 1 => State1(s), - 2 => State2(s), + 3 => State3(s), 4 => State4(s), 6 => State6(s), + 8 => State8(s), 9 => State9(s), - //10 => State10(s), - 12 => State12(s), 13 => State13(s), - 15 => State15(s), - 16 => State16(s), - 17 => State17(s), - 18 => State18(s), - 21 => State21(s), + 19 => State19(s), + 22 => State22(s), + 23 => State23(s), + 24 => State24(s), + 28 => State28(s), + 29 => State29(s), + 101 => State101(s), 102 => State102(s), @@ -75,111 +80,82 @@ public static class Controller { return acDcs.SystemControl == null || acDcs.Devices.Count == 0; } - - private static Boolean NotAvailable(this DcDcDevicesRecord dcDcs) - { - return dcDcs.SystemControl == null || dcDcs.Devices.Count == 0; - } - - - private static Boolean NotAvailable(this Battery48TlRecords batteries) - { - return batteries.Devices.Count <= 0; - } - private static Boolean State1(StatusRecord s) + private static Boolean State0(StatusRecord s) { - s.StateMachine.Message = "Inverters are off. Switching to Island Mode."; - - s.DcDc.Enable(); - s.AcDc.Enable(); - s.AcDc.EnableIslandMode(); - s.Relays.DisconnectIslandBusFromGrid(); + s.StateMachine.Message = "Ac/Dc are off. Switching to Island Mode."; - return false; - - // => 17 - } - - private static Boolean State2(StatusRecord s) - { - s.StateMachine.Message = "Inverters are disconnected from Island Bus. Switching to GridTie Mode. C"; - - s.DcDc.Disable(); - s.AcDc.Disable(); - s.AcDc.EnableGridTieMode(); - s.Relays.ConnectIslandBusToGrid(); - - return false; - - // => 10 - } - - private static Boolean State4(StatusRecord s) - { - s.StateMachine.Message = "Turning on Inverters"; - - s.DcDc.Enable(); - s.AcDc.Enable(); - s.AcDc.EnableGridTieMode(); - s.Relays.ConnectIslandBusToGrid(); - - return false; - - // => 12 - } - - - private static Boolean State6(StatusRecord s) - { - s.StateMachine.Message = "Inverters are off. Waiting for them to disconnect from Island Bus."; - s.DcDc.Disable(); s.AcDc.Disable(); s.AcDc.EnableIslandMode(); s.Relays.DisconnectIslandBusFromGrid(); - return true; - - // => 2 - } + return false; + // => 8 + } private static Boolean State9(StatusRecord s) { + s.StateMachine.Message = "Ac/Dc are disconnected from Island Bus. Switching to GridTie Mode."; - s.StateMachine.Message = "Inverters have disconnected from Island Bus. Turning them off."; - - s.DcDc.Disable(); // TODO: leave enabled? + s.DcDc.Disable(); s.AcDc.Disable(); s.AcDc.EnableGridTieMode(); s.Relays.DisconnectIslandBusFromGrid(); - return true; + return false; // => 1 } - - // - // private static Boolean State10(StatusRecord s) - // { - // - // s.SystemState.Message = "Inverters have disconnected from AcOut. Turning them off."; - // - // s.DcDc.Disable(); // TODO: leave enabled? - // s.AcDc.Disable(); - // s.AcDc.EnableGridTieMode(); - // s.Relays.DisconnectIslandBusFromGrid(); - // - // return true; - // - // // => 12 - // } - - private static Boolean State12(StatusRecord s) + private static Boolean State1(StatusRecord s) { - s.StateMachine.Message = "Waiting for Inverters to connect to Island Bus"; + s.StateMachine.Message = "Grid Tied mode active, closing k2"; + + s.DcDc.Disable(); + s.AcDc.Disable(); + s.AcDc.EnableGridTieMode(); + s.Relays.ConnectIslandBusToGrid(); + + return false; + + // => 3 + } + + private static Boolean State3(StatusRecord s) + { + s.StateMachine.Message = "K2 closed, Turning on Ac/Dc"; + + s.DcDc.Enable(); + s.AcDc.Enable(); + s.AcDc.EnableGridTieMode(); + s.Relays.ConnectIslandBusToGrid(); + + return false; + + // => 19 + } + + private static Boolean State13(StatusRecord s) + { + s.StateMachine.Message = "Ac/Dc are off. Waiting for them to disconnect from Island Bus."; + + s.DcDc.Disable(); + s.AcDc.Disable(); + s.AcDc.EnableIslandMode(); + s.Relays.DisconnectIslandBusFromGrid(); + + return true; + + // => 9 + } + + + + private static Boolean State19(StatusRecord s) + { + s.StateMachine.Message = "Waiting for Ac/Dc to connect to Island Bus"; s.DcDc.Enable(); s.AcDc.Enable(); @@ -188,66 +164,71 @@ public static class Controller return true; - // => 16 + // => 23 } - - private static Boolean State13(StatusRecord s) + private static Boolean State23(StatusRecord s) { - s.StateMachine.Message = "Disconnected from AcIn (K2), awaiting inverters to disconnect from AcOut (K3)"; - - s.DcDc.Enable(); - s.AcDc.Enable(); - s.AcDc.EnableGridTieMode(); - s.Relays.DisconnectIslandBusFromGrid(); - - return true; - - // => 9 - } - - private static Boolean State15(StatusRecord s) - { - s.StateMachine.Message = "Grid has been lost, disconnecting AcIn from AcOut (K2)"; - - s.DcDc.Enable(); - s.AcDc.Enable(); - s.AcDc.EnableGridTieMode(); - s.Relays.DisconnectIslandBusFromGrid(); - - return true; - - // => 13 - } - - private static Boolean State16(StatusRecord s) - { - // return new - // ( - // " Inverter is in grid-tie\n Waiting for K1AcInIsConnectedToGrid to open to leave it", - // AcPowerStageEnable: true, - // DcPowerStageEnable: true, - // GridType.GridTied400V50Hz, - // HighActivePinState.Closed - // ); - s.StateMachine.Message = "ESS"; s.DcDc.Enable(); s.AcDc.Enable(); s.AcDc.EnableGridTieMode(); + s.EnableDcLinkGridTie(); s.Relays.ConnectIslandBusToGrid(); return true; - // => 15 + // => 22 + } + + private static Boolean State22(StatusRecord s) + { + s.StateMachine.Message = "K1 opened, switching inverters off"; + + s.DcDc.Disable(); + s.AcDc.Disable(); + s.AcDc.EnableGridTieMode(); + s.Relays.ConnectIslandBusToGrid(); + + return true; + + // => 6 } - private static Boolean State17(StatusRecord s) + private static Boolean State6(StatusRecord s) { - s.StateMachine.Message = "Inverters are in Island Mode. Waiting for them to connect to AcIn."; + s.StateMachine.Message = "Inverters are off, opening K2"; + + s.DcDc.Disable(); + s.AcDc.Disable(); + s.AcDc.EnableGridTieMode(); + s.Relays.DisconnectIslandBusFromGrid(); + + return true; + + // => 4 + } + + private static Boolean State4(StatusRecord s) + { + s.StateMachine.Message = "K2 is open, waiting K3 to open"; + + s.DcDc.Disable(); + s.AcDc.Disable(); + s.AcDc.EnableGridTieMode(); + s.Relays.DisconnectIslandBusFromGrid(); + + return true; + + // => 0 + } + + private static Boolean State8(StatusRecord s) + { + s.StateMachine.Message = "Ac/Dc are off and in Island Mode."; s.DcDc.Enable(); s.AcDc.Enable(); @@ -255,48 +236,27 @@ public static class Controller s.Relays.DisconnectIslandBusFromGrid(); return true; - - // => 21 + // => 24 } - - - private static Boolean State18(StatusRecord s) - { - // return new - // ( - // " Didn't succeed to go to Island mode and K1AcInIsConnectedToGrid close\n Turning off power stage of inverter\n Moving to Grid Tie", - // AcPowerStageEnable: false, - // DcPowerStageEnable: false, - // GridType.GridTied400V50Hz, - // HighActivePinState.Open - // ); - - s.DcDc.Disable(); - s.AcDc.Disable(); - s.AcDc.EnableIslandMode(); - s.Relays.DisconnectIslandBusFromGrid(); - - return true; - } - - private static Boolean State21(StatusRecord s) + private static Boolean State28(StatusRecord s) { s.StateMachine.Message = "Island Mode"; s.DcDc.Enable(); s.AcDc.Enable(); s.AcDc.EnableIslandMode(); + s.EnableDcLinkIslandMode(); s.Relays.DisconnectIslandBusFromGrid(); return false; - // => 22 + // => 29 } - - private static Boolean State22(StatusRecord s) + + private static Boolean State29(StatusRecord s) { - s.StateMachine.Message = "Grid became available (K1). Turning off inverters."; + s.StateMachine.Message = "K1 closed, Switching off Inverters and moving to grid tie"; s.DcDc.Disable(); s.AcDc.Disable(); @@ -305,13 +265,23 @@ public static class Controller return false; - // => 6 + // => 13 } + + private static Boolean State24(StatusRecord s) + { + s.StateMachine.Message = "Inverter are on waiting for k3 to close"; + + s.DcDc.Enable(); + s.AcDc.Enable(); + s.AcDc.EnableIslandMode(); + s.Relays.DisconnectIslandBusFromGrid(); + return false; + + // => 28 + } - - - private static Boolean State101(StatusRecord s) { s.StateMachine.Message = "Relay device is not available"; @@ -324,24 +294,22 @@ public static class Controller return s.EnableSafeDefaults(); } - private static Boolean State103(StatusRecord s) { - s.StateMachine.Message = "Panic: ACDCs have unequal grid types"; + s.StateMachine.Message = "Panic: ACDCs have unequal grid types or PowerStage"; return s.EnableSafeDefaults(); } - private static Boolean State104(StatusRecord s) - { - s.StateMachine.Message = "Panic: DCDCs not available"; - return s.EnableSafeDefaults(); - } + // private static Boolean State104(StatusRecord s) + // { + // s.StateMachine.Message = "Panic: DCDCs not available"; + // return s.EnableSafeDefaults(); + // } private static Boolean UnknownState(StatusRecord s) { // "Unknown System State" - return s.EnableSafeDefaults(); } @@ -351,7 +319,21 @@ public static class Controller { return acDcs.Devices.All(d => !d.Control.PowerStageEnable); } + + private static Boolean AllEnabled(this AcDcDevicesRecord acDcs) + { + return acDcs.Devices.All(d => d.Control.PowerStageEnable); + } + + private static Boolean AllTheSame(this AcDcDevicesRecord acDcs) + { + return acDcs.Devices + .Select(d => d.Control.PowerStageEnable) + .Distinct() + .Count() == 1; + } + private static Boolean AllGridTied(this AcDcDevicesRecord acDcs) { return acDcs.Devices.All(d => d.Status.ActiveGridType is GridTied380V60Hz) @@ -381,9 +363,12 @@ public static class Controller private static void Disable(this DcDcDevicesRecord dcDc) { - dcDc.Devices - .Select(d => d.Control) - .ForAll(c => c.PowerStageEnable = false); + // For Test purpose, The transition from island mode to grid tier and vis versa , may not need to disable Dc/Dc. + // This will keep the Dc link powered. + + // dcDc.Devices + // .Select(d => d.Control) + // .ForAll(c => c.PowerStageEnable = false); } private static void Enable(this AcDcDevicesRecord acDc) @@ -393,7 +378,6 @@ public static class Controller .ForAll(c => c.PowerStageEnable = true); } - private static void Enable(this DcDcDevicesRecord dcDc) { dcDc.Devices @@ -402,7 +386,6 @@ public static class Controller } - private static void EnableGridTieMode(this AcDcDevicesRecord acDc) { acDc.Devices @@ -417,7 +400,34 @@ public static class Controller .Select(d => d.Control) .ForAll(c => c.Ac.GridType = Island400V50Hz); // TODO: config grid type } + + private static void EnableDcLinkIslandMode(this StatusRecord s) + { + // Dc Link Windows on AcDc +- 60 + s.Config.ReferenceDcLinkVoltageFromAcDc = 750; + s.Config.MinDcLinkVoltageFromAcDc = 690; + s.Config.MaxDcLinkVoltageFromAcDc = 810; + + // Dc Link Windows on DcDc +-55 + s.Config.ReferenceDcLinkVoltageFromDc = 750; + s.Config.UpperDcLinkVoltageFromDc = 55; + s.Config.LowerDcLinkVoltageFromDc = 55; + } + private static void EnableDcLinkGridTie(this StatusRecord s) + { + // Dc Link Windows on DcDc +-30 + + s.Config.ReferenceDcLinkVoltageFromAcDc = 750; + s.Config.MinDcLinkVoltageFromAcDc = 720; + s.Config.MaxDcLinkVoltageFromAcDc = 780; + + // Dc Link Windows on DcDc +-20 + s.Config.ReferenceDcLinkVoltageFromDc = 750; + s.Config.UpperDcLinkVoltageFromDc = 20; + s.Config.LowerDcLinkVoltageFromDc = 20; + } + private static void DisconnectIslandBusFromGrid(this RelaysRecord? relays) { if (relays is not null) @@ -433,15 +443,16 @@ public static class Controller private static Boolean EnableSafeDefaults(this StatusRecord s) { - s.DcDc.Disable(); - s.AcDc.Disable(); - s.AcDc.EnableGridTieMode(); - s.Relays.DisconnectIslandBusFromGrid(); + // After some tests, the safe state is switch off inverter and keep the last state of K2 , Dc/Dc and Grid type to avoid conflict. + // s.DcDc.Disable(); + s.AcDc.Disable(); + // s.AcDc.EnableGridTieMode(); + // s.Relays.DisconnectIslandBusFromGrid(); return false; } - private static DcDcDevicesRecord ResetAlarms(this DcDcDevicesRecord dcDcStatus) + public static DcDcDevicesRecord ResetAlarms(this DcDcDevicesRecord dcDcStatus) { var sc = dcDcStatus.SystemControl; @@ -454,7 +465,7 @@ public static class Controller return dcDcStatus; } - private static AcDcDevicesRecord ResetAlarms(this AcDcDevicesRecord acDcStatus) + public static AcDcDevicesRecord ResetAlarms(this AcDcDevicesRecord acDcStatus) { var sc = acDcStatus.SystemControl; diff --git a/csharp/App/SaliMax/src/SystemConfig/Config.cs b/csharp/App/SaliMax/src/SystemConfig/Config.cs index 426bcf294..c096ca5aa 100644 --- a/csharp/App/SaliMax/src/SystemConfig/Config.cs +++ b/csharp/App/SaliMax/src/SystemConfig/Config.cs @@ -14,48 +14,52 @@ public class Config //TODO: let IE choose from config files (Json) and connect t private static readonly JsonSerializerOptions JsonOptions = new() { WriteIndented = true }; - public required Double MinSoc { get; set; } - public required UnixTime LastEoc { get; set; } - public required Double PConstant { get; set; } - public required Double GridSetPoint { get; set; } - public required Double BatterySelfDischargePower { get; set; } - public required Double HoldSocZone { get; set; } + public required Double MinSoc { get; set; } + public required UnixTime LastEoc { get; set; } + public required Double PConstant { get; set; } + public required Double GridSetPoint { get; set; } + public required Double BatterySelfDischargePower { get; set; } + public required Double HoldSocZone { get; set; } - public required Double MaxDcLinkVoltageFromAcDc { get; set; } - public required Double MinDcLinkVoltageFromAcDc { get; set; } - public required Double ReferenceDcLinkVoltageFromAcDc { get; set; } + public required Double MaxDcLinkVoltageFromAcDc { get; set; } + public required Double MinDcLinkVoltageFromAcDc { get; set; } + public required Double ReferenceDcLinkVoltageFromAcDc { get; set; } - public required Double LowerDcLinkVoltageFromDc { get; set; } - public required Double ReferenceDcLinkVoltageFromDc { get; set; } - public required Double UpperDcLinkVoltageFromDc { get; set; } + public required Double LowerDcLinkVoltageFromDc { get; set; } + public required Double ReferenceDcLinkVoltageFromDc { get; set; } + public required Double UpperDcLinkVoltageFromDc { get; set; } - public required Double MaxBatteryChargingCurrent { get; set; } - public required Double MaxBatteryDischargingCurrent { get; set; } + public required Double MaxBatteryChargingCurrent { get; set; } + public required Double MaxBatteryDischargingCurrent { get; set; } - public required Double MaxChargeBatteryVoltage { get; set; } - public required Double MinDischargeBatteryVoltage { get; set; } + public required Double MaxChargeBatteryVoltage { get; set; } + public required Double MinDischargeBatteryVoltage { get; set; } - public required DeviceConfig Devices { get; set; } - public required S3Config? S3 { get; set; } + public required DeviceConfig Devices { get; set; } + public required S3Config? S3 { get; set; } #if DEBUG public static Config Default => new() { - MinSoc = 20, - LastEoc = UnixTime.Epoch, // TODO: remove, use new LastEoc feature from BMS - PConstant = .5, - GridSetPoint = 0, - BatterySelfDischargePower = 200, - HoldSocZone = 1, // TODO: find better name, - MinDcBusVoltage = 690, - ReferenceDcBusVoltage = 750, - MaxDcBusVoltage = 810, - LowerDcBusVoltageWindow = 50, - ReferenceDcBusVoltageWindow = 750, - UpperDcBusVoltageWindow = 50, - Devices = new () + MinSoc = 20, + LastEoc = UnixTime.Epoch, // TODO: remove, use new LastEoc feature from BMS + PConstant = .5, + GridSetPoint = 0, + BatterySelfDischargePower = 200, + HoldSocZone = 1, // TODO: find better name, + MinDcLinkVoltageFromAcDc = 690, + ReferenceDcLinkVoltageFromAcDc = 750, + MaxDcLinkVoltageFromAcDc = 810, + LowerDcLinkVoltageFromDc = 50, + ReferenceDcLinkVoltageFromDc = 750, + UpperDcLinkVoltageFromDc = 50, + MaxBatteryChargingCurrent = 210, + MaxBatteryDischargingCurrent = 210, + MaxChargeBatteryVoltage = 57, + MinDischargeBatteryVoltage = 0, + Devices = new () { TruConvertAcIp = new() { Host = "localhost", Port = 5001}, TruConvertDcIp = new() { Host = "localhost", Port = 5002}, diff --git a/csharp/App/SaliMax/src/Topology.cs b/csharp/App/SaliMax/src/Topology.cs new file mode 100644 index 000000000..00345a4ff --- /dev/null +++ b/csharp/App/SaliMax/src/Topology.cs @@ -0,0 +1,254 @@ +using System.Diagnostics.CodeAnalysis; +using InnovEnergy.App.SaliMax.Ess; +using InnovEnergy.Lib.Devices.Battery48TL; +using InnovEnergy.Lib.Units; +using InnovEnergy.Lib.Units.Power; +using InnovEnergy.Lib.Utils; +using Ac3Bus = InnovEnergy.Lib.Units.Composite.Ac3Bus; + +namespace InnovEnergy.App.SaliMax; + +public static class Topology +{ + public static TextBlock From(this StatusRecord s) + { + // Topology is built up from right to left + + // Power Measurement Values + + var inverterPower = s.AcDc.Ac.Power.Active; + var islandLoadPower = s.LoadOnAcIsland is not null + ? s.LoadOnAcIsland.Ac.Power.Active + : 0; // TODO + + var islandTopology = CreateIslandTopology(s, islandLoadPower, inverterPower); + + if (s.GridMeter is null) // no grid meter? + return islandTopology; // we're done + + var gridBusColumn = GridBusColumn(s); + var gridBox = CreateGridBox(s); + + ActivePower islandToGridBusPower = inverterPower + islandLoadPower; + + // return TextBlock + // .AlignCenterVertical + // ( + // gridBox , Flow.Horizontal(s.GridMeter.Ac.Power.Active), + // gridBusColumn, Flow.Horizontal(islandToGridBusPower), + // islandTopology + // ); + + var gridTopology = TextBlock + .AlignCenterVertical + ( + gridBox, + Flow.Horizontal(s.GridMeter.Ac.Power.Active), + gridBusColumn + ); + + return TextBlock.AlignCenterVertical + ( + gridTopology, + Flow.Horizontal(islandToGridBusPower), + islandTopology + ); + } + + private static TextBlock CreateIslandTopology(StatusRecord s, ActivePower islandLoadPower, ActivePower inverterPower) + { + var dcBatteryPower = s.DcDc.Dc.Battery.Power; + var dcdcPower = s.DcDc.Dc.Link.Power; + + var batteries = CreateBatteryColumn(s); + var dcBusColumn = CreateDcBusColumn(s); + var islandBusColumn = CreateIslandBusColumn(s, islandLoadPower); + var inverterBox = CreateInverterBox(s); + var dcDcBox = CreateDcDcBox(s); + + return TextBlock + .AlignCenterVertical + ( + islandBusColumn, Flow.Horizontal(inverterPower), + inverterBox , Flow.Horizontal(inverterPower), + dcBusColumn , Flow.Horizontal(dcdcPower), + dcDcBox , Flow.Horizontal(dcBatteryPower), + batteries + ); + } + + private static TextBlock CreateGridBox(StatusRecord statusRecord) + { + return statusRecord + .GridMeter! + .Ac + .PhasePowersActive() + .TitleBox("Grid"); + } + + private static TextBlock CreateDcDcBox(StatusRecord s) + { + var dc48Voltage = s.DcDc.Dc.Battery.Voltage.ToDisplayString(); + + return TextBlock + .AlignLeft(dc48Voltage) + .TitleBox("DC/DC"); + } + + private static TextBlock CreateInverterBox(StatusRecord s) + { + var inverterAcPhases = s + .AcDc + .Devices + .Select(d => d.Status.Ac.Power) + .ToReadOnlyList(); + + return TextBlock + .AlignLeft(inverterAcPhases) + .TitleBox("AC/DC"); + } + + private static TextBlock CreateIslandBusColumn(StatusRecord s, ActivePower islandLoadPower) + { + var islandBusPv = 0.W(); // TODO + + return ColumnBox + ( + "Pv", islandBusPv, + "Island Bus", s.AcDc.Ac.PhasePowersActive(), + "Load", islandLoadPower + ); + } + + private static TextBlock CreateDcBusColumn(StatusRecord s) + { + var dcBusLoad = 0.W(); // TODO + var pvOnDcPower = s.PvOnDc.Dc!.Power; // TODO ! + var dcLinkVoltage = s.DcDc.Dc.Link.Voltage.ToDisplayString(); + + return ColumnBox + ( + "Pv" , pvOnDcPower, + "Dc Bus", dcLinkVoltage, + "Load" , dcBusLoad + ); + } + + private static TextBlock CreateBatteryColumn(StatusRecord s) + { + var bat = s.Battery; + var batteryAvgBox = CreateAveragedBatteryBox(bat); + + var batteryBoxes = bat + .Devices + .Select(CreateIndividualBattery) + .ToReadOnlyList(); + + var individualBatteries = batteryBoxes.Any() + ? TextBlock.AlignLeft(batteryBoxes) + : TextBlock.Empty; + + return TextBlock + .AlignCenterVertical + ( + batteryAvgBox //, + //individualBatteries // TODO + ); + } + + private static TextBlock CreateAveragedBatteryBox(Battery48TlRecords bat) + { + var batteryVoltage = bat.Dc.Voltage.ToDisplayString(); + var batterySoc = bat.Devices.Any() ? bat.Devices.Average(b => b.Soc).Percent().ToDisplayString() : "0"; + var batteryCurrent = bat.Dc.Current.ToDisplayString(); + var batteryTemp = bat.Temperature.ToDisplayString(); + var batteryHeatingCurrent = bat.HeatingCurrent.ToDisplayString(); + var alarms = bat.Alarms.Count + " Alarms"; + var warnings = bat.Warnings.Count + " Warnings"; + + return TextBlock + .AlignLeft + ( + batteryVoltage, + batterySoc, + batteryCurrent, + batteryTemp, + batteryHeatingCurrent, + warnings, + alarms + ) + .TitleBox("Battery"); + } + + private static TextBlock GridBusColumn(StatusRecord s) + { + var gridLoadPower = s.LoadOnAcGrid is not null + ? s.LoadOnAcGrid.Power.Active + : 0; // TODO: show that LoadOnAcGrid is actually not available and not 0 + + return ColumnBox + ( + "Pv", 0, + "Grid Bus", s.GridMeter!.Ac.PhaseVoltages(), + "Load", gridLoadPower + ); + } + + private static TextBlock PhaseVoltages(this Ac3Bus ac) + { + return TextBlock.AlignLeft + ( + ac.L1.Voltage.ToDisplayString(), + ac.L2.Voltage.ToDisplayString(), + ac.L3.Voltage.ToDisplayString() + ); + } + + private static TextBlock PhasePowersActive(this Ac3Bus ac) + { + return TextBlock.AlignLeft + ( + ac.L1.Power.Active.ToDisplayString(), + ac.L2.Power.Active.ToDisplayString(), + ac.L3.Power.Active.ToDisplayString() + ); + } + + private static TextBlock CreateIndividualBattery(Battery48TlRecord battery, Int32 i) + { + var batteryWarnings = battery.Warnings.Any(); + var batteryAlarms = battery.Alarms.Any(); + + var content = TextBlock.AlignLeft + ( + battery.Dc.Voltage.ToDisplayString(), + battery.Soc.ToDisplayString(), + battery.Dc.Current.ToDisplayString() + " C/D", + battery.Temperatures.Cells.Average.ToDisplayString(), + battery.BusCurrent.ToDisplayString() + " T", + batteryWarnings, + batteryAlarms, + battery.HeatingCurrent.ToDisplayString() + " H" + ); + + var box = content.TitleBox($"Battery {i + 1}"); + var flow = Flow.Horizontal(battery.Dc.Power); + + return TextBlock.AlignCenterVertical(flow, box); + } + + [SuppressMessage("ReSharper", "SuggestBaseTypeForParameter")] + + private static TextBlock ColumnBox(String pvTitle , ActivePower pvPower, + String busTitle , Object busData, + String loadTitle, ActivePower loadPower) + { + var pvBox = TextBlock.FromString(pvTitle).Box(); + var pvToBus = Flow.Vertical(pvPower); + var busBox = TextBlock.AlignLeft(busData).TitleBox(busTitle); + var busToLoad = Flow.Vertical(loadPower); + var loadBox = TextBlock.FromString(loadTitle).Box(); + + return TextBlock.AlignCenterHorizontal(pvBox, pvToBus, busBox, busToLoad, loadBox); + } +} \ No newline at end of file diff --git a/csharp/App/SaliMax/src/Watchdog.cs b/csharp/App/SaliMax/src/Watchdog.cs new file mode 100644 index 000000000..e93bac272 --- /dev/null +++ b/csharp/App/SaliMax/src/Watchdog.cs @@ -0,0 +1,15 @@ +using System.Runtime.InteropServices; + +namespace InnovEnergy.App.SaliMax; + +// https://www.freedesktop.org/software/systemd/man/sd_notify.html + +public static class Watchdog +{ + // "it is generally recommended to ignore the return value of this call. " + [DllImport("libsystemd.so.0")] + private static extern Int32 sd_notify(Int32 unsetEnvironment, String state); + + public static void Ready() => _ = sd_notify(0, "READY=1"); + public static void Alive() => _ = sd_notify(0, "WATCHDOG=1"); +} \ No newline at end of file diff --git a/csharp/App/SaliMax/tunnelstoSalimaxX.sh b/csharp/App/SaliMax/tunnelstoSalimaxX.sh index b3676d486..f7c65bea5 100755 --- a/csharp/App/SaliMax/tunnelstoSalimaxX.sh +++ b/csharp/App/SaliMax/tunnelstoSalimaxX.sh @@ -8,7 +8,7 @@ tunnel() { rPort=$3 lPort=$4 - echo -n "localhost:$lPort $name " + echo -n "$name @ $ip mapped to localhost:$lPort " ssh -nNTL "$lPort:$ip:$rPort" "$host" 2> /dev/null & until nc -vz 127.0.0.1 $lPort 2> /dev/null @@ -22,23 +22,23 @@ tunnel() { echo "" -tunnel "Trumpf Inverter (http) " 10.0.2.1 80 7001 -tunnel "Trumpf DCDC (http) " 10.0.3.1 80 7002 -tunnel "Ext Emu Meter (http) " 10.0.4.1 80 7003 -tunnel "Int Emu Meter (http) " 10.0.4.2 80 7004 -tunnel "AMPT (http) " 10.0.5.1 8080 7005 -tunnel "Doepke (http) " 10.0.6.1 80 7006 +tunnel "Trumpf Inverter (http) " 10.0.2.1 80 8001 +tunnel "Trumpf DCDC (http) " 10.0.3.1 80 8002 +tunnel "Ext Emu Meter (http) " 10.0.4.1 80 8003 +tunnel "Int Emu Meter (http) " 10.0.4.2 80 8004 +tunnel "AMPT (http) " 10.0.5.1 8080 8005 tunnel "Trumpf Inverter (modbus)" 10.0.2.1 502 5001 tunnel "Trumpf DCDC (modbus) " 10.0.3.1 502 5002 tunnel "Ext Emu Meter (modbus) " 10.0.4.1 502 5003 tunnel "Int Emu Meter " 10.0.4.2 502 5004 tunnel "AMPT (modbus) " 10.0.5.1 502 5005 -tunnel "Batteries " 127.0.0.1 6855 5007 - +tunnel "Adam " 10.0.1.1 502 5006 +tunnel "Batteries " 127.0.0.1 6855 5007 echo echo "press any key to close the tunnels ..." read -r -n 1 -s kill $(jobs -p) echo "done" + diff --git a/csharp/App/VrmGrabber/Program.cs b/csharp/App/VrmGrabber/Program.cs index 772951f5f..693f847cc 100644 --- a/csharp/App/VrmGrabber/Program.cs +++ b/csharp/App/VrmGrabber/Program.cs @@ -24,7 +24,7 @@ public static class Program app.MapControllers(); // app.MapGet("/", () => Controller.Index()); var webTask = app.RunAsync(); - await Task.WhenAll(webTask); + await Task.WhenAll(webTask, updateTask); } private static OpenApiInfo OpenApiInfo { get; } = new OpenApiInfo diff --git a/csharp/Lib/Channels/Framed/Channel.cs b/csharp/Lib/Channels/Framed/Channel.cs index e5ac24f1a..6137ff595 100644 --- a/csharp/Lib/Channels/Framed/Channel.cs +++ b/csharp/Lib/Channels/Framed/Channel.cs @@ -3,7 +3,7 @@ using InnovEnergy.Lib.Utils; namespace InnovEnergy.Lib.Channels.Framed; -public class Channel : Connection +public class Channel : Connection { private readonly AsyncAction _Transmit; private readonly Async _Receive; diff --git a/csharp/Lib/Devices/AMPT/AmptDevices.cs b/csharp/Lib/Devices/AMPT/AmptDevices.cs index 4e8b47256..69235615f 100644 --- a/csharp/Lib/Devices/AMPT/AmptDevices.cs +++ b/csharp/Lib/Devices/AMPT/AmptDevices.cs @@ -19,11 +19,10 @@ public class AmptDevices { } - public AmptDevices(ModbusClient modbusClient) { _CommunicationUnit = new ModbusDevice(modbusClient); - _StringOptimizers = StringOptimizers(modbusClient); + _StringOptimizers = StringOptimizers(modbusClient); } public AmptStatus Read() @@ -36,7 +35,7 @@ public class AmptDevices } catch (Exception e) { - Console.WriteLine( "Failed to read Ampt data \n"+ e.Message ); + Console.WriteLine("Failed to read Ampt data \n" + e.Message); // TODO: log } diff --git a/csharp/Lib/Devices/Battery48TL/Battery48TLDevice.cs b/csharp/Lib/Devices/Battery48TL/Battery48TLDevice.cs index b22f5d2e5..58e0b9144 100644 --- a/csharp/Lib/Devices/Battery48TL/Battery48TLDevice.cs +++ b/csharp/Lib/Devices/Battery48TL/Battery48TLDevice.cs @@ -7,7 +7,7 @@ using static System.IO.Ports.Parity; namespace InnovEnergy.Lib.Devices.Battery48TL; -public class Battery48TlDevice: ModbusDevice +public class Battery48TlDevice : ModbusDevice { public const Parity Parity = Odd; public const Int32 StopBits = 1; diff --git a/csharp/Lib/Devices/Battery48TL/Battery48TlDevices.cs b/csharp/Lib/Devices/Battery48TL/Battery48TlDevices.cs index 866d4a49d..7a2c3cb45 100644 --- a/csharp/Lib/Devices/Battery48TL/Battery48TlDevices.cs +++ b/csharp/Lib/Devices/Battery48TL/Battery48TlDevices.cs @@ -20,7 +20,7 @@ public class Battery48TlDevices } catch (Exception e) { - Console.WriteLine( "Failed to read Battery data \n"+ e.Message ); + Console.WriteLine("Failed to read Battery data \n" + e.Message); // TODO: log return Battery48TlRecords.Null; diff --git a/csharp/Lib/Devices/Battery48TL/Battery48TlRecord.Api.cs b/csharp/Lib/Devices/Battery48TL/Battery48TlRecord.Api.cs index 9f99e104c..0bc4a0869 100644 --- a/csharp/Lib/Devices/Battery48TL/Battery48TlRecord.Api.cs +++ b/csharp/Lib/Devices/Battery48TL/Battery48TlRecord.Api.cs @@ -94,24 +94,23 @@ public partial class Battery48TlRecord if (HasBit(14)) yield return "FUSE : Main fuse blown"; if (HasBit(15)) yield return "HTRE : Battery failed to warm up"; if (HasBit(16)) yield return "TCPE : Temperature sensor failure"; - if (HasBit(17)) yield return "STRE :"; + if (HasBit(17)) yield return "STRE : Voltage measurement circuit fails"; if (HasBit(18)) yield return "CME : Current sensor failure"; if (HasBit(19)) yield return "HWFL : BMS hardware failure"; if (HasBit(20)) yield return "HWEM : Hardware protection tripped"; if (HasBit(21)) yield return "ThM : Heatsink temperature too high"; - if (HasBit(22)) yield return "vsm1 : String voltage too low"; if (HasBit(23)) yield return "vsm2 : Low string voltage failure"; if (HasBit(25)) yield return "vsM2 : String voltage too high"; if (HasBit(27)) yield return "iCM2 : Charge current too high"; if (HasBit(29)) yield return "iDM2 : Discharge current too high"; if (HasBit(31)) yield return "MID2 : String voltage unbalance too high"; - if (HasBit(33)) yield return "CCBF : Internal charger hardware failure"; - if (HasBit(34)) yield return "AhFL :"; - if (HasBit(36)) yield return "TbCM :"; - if (HasBit(37)) yield return "BRNF :"; + // if (HasBit(34)) yield return "AhFL :"; // This is doesn't exist in the manual + // if (HasBit(36)) yield return "TbCM :"; // This is doesn't exist in the manual + // if (HasBit(37)) yield return "BRNF :"; // This is doesn't exist in the manual if (HasBit(42)) yield return "HTFS : Heater Fuse Blown"; if (HasBit(43)) yield return "DATA : Parameters out of range"; - if (HasBit(45)) yield return "CELL2:"; + if (HasBit(45)) yield return "CELL2: Unbalance string voltages"; + if (HasBit(46)) yield return "HEBT : Loss of heartbeat"; } [SuppressMessage("ReSharper", "StringLiteralTypo")] @@ -124,18 +123,20 @@ public partial class Battery48TlRecord if (HasBit(6) ) yield return "VBm1: Bus voltage low"; if (HasBit(8) ) yield return "VBM1: Bus voltage high"; if (HasBit(10)) yield return "IDM1: Discharge current high"; + if (HasBit(22)) yield return "vsm1: String voltage too low"; if (HasBit(24)) yield return "vsM1: String voltage high"; if (HasBit(26)) yield return "iCM1: Charge current high"; if (HasBit(28)) yield return "iDM1: Discharge current high"; if (HasBit(30)) yield return "MID1: String voltages unbalanced"; if (HasBit(32)) yield return "BLPW: Not enough charging power on bus"; + if (HasBit(33)) yield return "CCBF : Internal charger hardware failure"; if (HasBit(35)) yield return "Ah_W: String SOC low"; if (HasBit(38)) yield return "MPMM: Midpoint wiring problem"; - if (HasBit(39)) yield return "TCMM:"; + // if (HasBit(39)) yield return "TCMM:"; // This is doesn't exist in the manual if (HasBit(40)) yield return "TCdi: Temperature difference between strings high"; - if (HasBit(41)) yield return "WMTO:"; - if (HasBit(44)) yield return "bit44:"; - if (HasBit(46)) yield return "CELL1:"; + // if (HasBit(41)) yield return "WMTO:"; // This is doesn't exist in the manual + if (HasBit(44)) yield return "LMPW : String voltages unbalance warning"; + if (HasBit(47)) yield return "TOCW : "; } diff --git a/csharp/Lib/Devices/Battery48TL/Battery48TlRecord.Modbus.cs b/csharp/Lib/Devices/Battery48TL/Battery48TlRecord.Modbus.cs index e2bf89a13..249ba4283 100644 --- a/csharp/Lib/Devices/Battery48TL/Battery48TlRecord.Modbus.cs +++ b/csharp/Lib/Devices/Battery48TL/Battery48TlRecord.Modbus.cs @@ -30,6 +30,16 @@ public partial class Battery48TlRecord [InputRegister(1017, Scale = 0.1, Offset = -400)] private Double _TemperaturesCellsRight; [InputRegister(1003, Scale = 0.1, Offset = -400)] private Double _TemperaturesCellsAverage; + + [InputRegister(1054)] private Double _FwVersion; + [InputRegister(1055)] private Double _SerialNum1; + [InputRegister(1056)] private Double _SerialNum2; + [InputRegister(1057)] private Double _SerialNum3; + [InputRegister(1058)] private Double _SerialNum4; + [InputRegister(1059)] private Double _LimpBitMap; + [InputRegister(1060)] private Double _BatteryState1; + [InputRegister(1061)] private Double _BatteryState2; + private LedState ParseLed(LedColor led) => (LedState)((_LedStates >> (Int32)led) & 3); // public Decimal CellsVoltage { get; init; } diff --git a/csharp/Lib/Devices/Battery48TL/Battery48TlRecords.cs b/csharp/Lib/Devices/Battery48TL/Battery48TlRecords.cs index 06b6ac12e..8d13298c1 100644 --- a/csharp/Lib/Devices/Battery48TL/Battery48TlRecords.cs +++ b/csharp/Lib/Devices/Battery48TL/Battery48TlRecords.cs @@ -19,7 +19,7 @@ public class Battery48TlRecords HeatingCurrent = records.Any() ? records.Sum(b => b.HeatingCurrent) : 0; Dc = empty - ? DcBus.FromVoltageCurrent(0, 0) + ? DcBus.Null : DcBus.FromVoltageCurrent ( records.Average(r => r.Dc.Voltage), diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/Control/DcControl.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/Control/DcControl.cs index baac43651..33601ad6a 100644 --- a/csharp/Lib/Devices/Trumpf/TruConvertAc/Control/DcControl.cs +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/Control/DcControl.cs @@ -36,8 +36,12 @@ public class DcControl } } - public DcPrechargeConfig PrechargeConfig => _Self.DcPrechargeConfig; - + public DcPrechargeConfig PrechargeConfig + { + get { return _Self.DcPrechargeConfig; } + set { _Self.DcPrechargeConfig = value; } + } + private Boolean Is480V => _Self.GridType is GridType.GridTied480V60Hz or GridType.Island480V60Hz; internal DcControl(AcDcRecord self) => _Self = self; diff --git a/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/DcPrechargeConfig.cs b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/DcPrechargeConfig.cs index 7eddb6be1..e5b2563b3 100644 --- a/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/DcPrechargeConfig.cs +++ b/csharp/Lib/Devices/Trumpf/TruConvertAc/DataTypes/DcPrechargeConfig.cs @@ -3,7 +3,7 @@ namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes; public enum DcPrechargeConfig : UInt16 { WaitForExternalPrecharge = 0, - PrechargeDcWithSystemCtl = 1, + PrechargeDcWithInternal = 1, PrechargeDcWithDcDcs = 2, PrechargeDcWithSystemCtlAndWait = 3, } \ No newline at end of file diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/CurrentControl.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/CurrentControl.cs index a37303051..152d8a56f 100644 --- a/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/CurrentControl.cs +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/Control/CurrentControl.cs @@ -15,6 +15,19 @@ public class CurrentControl get => _Self.MaxCurrentChangePerMs; set => _Self.MaxCurrentChangePerMs = value.Value; } + + public Current MaxBatteryChargingCurrent + { + get => _Self.MaxBatteryChargingCurrent; + set => _Self.MaxBatteryChargingCurrent = value.Value; + } + + public Current MaxBatteryDischargingCurrent + { + get => _Self.MaxBatteryDischargingCurrent; + set => _Self.MaxBatteryDischargingCurrent = value.Value; + } + private readonly DcDcRecord _Self; internal CurrentControl(DcDcRecord self) => _Self = self; diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/DcDcRecord.Modbus.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/DcDcRecord.Modbus.cs index c58364efb..59525b119 100644 --- a/csharp/Lib/Devices/Trumpf/TruConvertDc/DcDcRecord.Modbus.cs +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/DcDcRecord.Modbus.cs @@ -20,11 +20,14 @@ public partial class DcDcRecord [HoldingRegister(4100, Scale = .01)] internal Double MaxBatteryVoltage ; [HoldingRegister(4101, Scale = .01)] internal Double MinBatteryVoltage ; + [HoldingRegister(4106, Scale = .1)] internal Double MaxBatteryChargingCurrent ; + [HoldingRegister(4109, Scale = .1)] internal Double MaxBatteryDischargingCurrent ; + [HoldingRegister(4112, Scale = .1)] internal Double VccEndPointVoltage ; [HoldingRegister(4115)] internal Double VccEndPointCurrent ; [HoldingRegister(4118)] internal Double VccStartPointCurrent ; - [HoldingRegister(4118)] internal Double MaxDcPower ; + [HoldingRegister(4121)] internal Double MaxDcPower ; [HoldingRegister(4124, Scale = .1)] internal Double MaxVoltageAlarm ; [HoldingRegister(4127, Scale = .1)] internal Double MinVoltageAlarm ; diff --git a/csharp/Lib/Protocols/Modbus/Slaves/ModbusDevice.cs b/csharp/Lib/Protocols/Modbus/Slaves/ModbusDevice.cs index e04c4bef7..3f69f29a8 100644 --- a/csharp/Lib/Protocols/Modbus/Slaves/ModbusDevice.cs +++ b/csharp/Lib/Protocols/Modbus/Slaves/ModbusDevice.cs @@ -35,11 +35,11 @@ public class ModbusDevice<[DynamicallyAccessedMembers(All)] R> where R : notnull return Read(r); } - public R Read(R record) + public R Read(R record) { foreach (var batch in _Batches) batch.Read(record); - + return record; } diff --git a/csharp/Lib/Time/Unix/UnixTimeSpanExtensions.cs b/csharp/Lib/Time/Unix/UnixTimeSpanExtensions.cs index 625253a88..b5bd2b53f 100644 --- a/csharp/Lib/Time/Unix/UnixTimeSpanExtensions.cs +++ b/csharp/Lib/Time/Unix/UnixTimeSpanExtensions.cs @@ -9,8 +9,8 @@ public static class UnixTimeSpanExtensions public static UnixTimeSpan Weeks (this Int32 w) => UnixTimeSpan.FromWeeks (w); public static UnixTimeSpan Seconds(this UInt32 s) => UnixTimeSpan.FromSeconds(s); - public static UnixTimeSpan Minutes(this UInt32 m) => UnixTimeSpan.FromSeconds(m); - public static UnixTimeSpan Hours (this UInt32 h) => UnixTimeSpan.FromMinutes(h); - public static UnixTimeSpan Days (this UInt32 d) => UnixTimeSpan.FromHours (d); - public static UnixTimeSpan Weeks (this UInt32 w) => UnixTimeSpan.FromDays (w); + public static UnixTimeSpan Minutes(this UInt32 m) => UnixTimeSpan.FromMinutes(m); + public static UnixTimeSpan Hours (this UInt32 h) => UnixTimeSpan.FromHours (h); + public static UnixTimeSpan Days (this UInt32 d) => UnixTimeSpan.FromDays (d); + public static UnixTimeSpan Weeks (this UInt32 w) => UnixTimeSpan.FromWeeks (w); } \ No newline at end of file diff --git a/csharp/Lib/Units/Unit.cs b/csharp/Lib/Units/Unit.cs index 5e5997191..d478e179f 100644 --- a/csharp/Lib/Units/Unit.cs +++ b/csharp/Lib/Units/Unit.cs @@ -9,6 +9,11 @@ public abstract class Unit public override String ToString() => $"{Value} {Symbol}"; + private static readonly IReadOnlyList Prefix = new[] { "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Y" }; + + private static Int32 MaxPrefix { get; } = Prefix.Count - 1; + private static Int32 DefaultIndex { get; } = Prefix.TakeWhile(e => e != "").Count(); + public String ToDisplayString() { if (Value == 0) @@ -17,14 +22,14 @@ public abstract class Unit var a = Math.Abs(Value); var s = Math.Sign(Value); - var i = 8; + var i = DefaultIndex; - while (a >= 10000) + while (a >= 10000 && i < MaxPrefix) { a /= 1000; i++; } - while (a < 10) + while (a < 10 && i > 0) { a *= 1000; i--; @@ -37,6 +42,6 @@ public abstract class Unit return $"{r * s} {Prefix[i]}{Symbol}"; } - private static readonly IReadOnlyList Prefix = new[] { "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Y" }; + } diff --git a/csharp/Lib/Units/Units.cs b/csharp/Lib/Units/Units.cs index 50fae56a2..2044d91ae 100644 --- a/csharp/Lib/Units/Units.cs +++ b/csharp/Lib/Units/Units.cs @@ -23,6 +23,19 @@ public static class Units public static Energy Wh (this Double value) => value; public static Percent Percent(this Double value) => value; + public static Current A (this Int32 value) => value; + public static Voltage V (this Int32 value) => value; + public static ActivePower W (this Int32 value) => value; + public static ReactivePower Var (this Int32 value) => value; + public static ApparentPower Va (this Int32 value) => value; + public static Resistance Ohm (this Int32 value) => value; + public static Frequency Hz (this Int32 value) => value; + public static Angle Rad (this Int32 value) => value; + public static Temperature Celsius(this Int32 value) => value; + public static Energy KWh (this Int32 value) => value * 1000; + public static Energy Wh (this Int32 value) => value; + public static Percent Percent(this Int32 value) => value; + public static String ToCsv(this Object thing) { var csvLines = new List(); diff --git a/csharp/Lib/Utils/ArrayExtensions.cs b/csharp/Lib/Utils/ArrayExtensions.cs index a24c169b5..89abf990c 100644 --- a/csharp/Lib/Utils/ArrayExtensions.cs +++ b/csharp/Lib/Utils/ArrayExtensions.cs @@ -13,4 +13,6 @@ public static class ArrayExtensions Array.Fill(ts, element); return ts; } + + public static IReadOnlyList AsReadOnlyList(this T[] ts) => ts; } \ No newline at end of file diff --git a/csharp/Lib/Utils/ConsoleUtils.cs b/csharp/Lib/Utils/ConsoleUtils.cs index 9d5c42013..bfee3b9df 100644 --- a/csharp/Lib/Utils/ConsoleUtils.cs +++ b/csharp/Lib/Utils/ConsoleUtils.cs @@ -38,7 +38,6 @@ public static class ConsoleUtils return t; } - public static T Write(this T t, ConsoleColor color) { var c = Console.ForegroundColor; diff --git a/csharp/Lib/Utils/EnumerableUtils.cs b/csharp/Lib/Utils/EnumerableUtils.cs index 10d777f5b..008629086 100644 --- a/csharp/Lib/Utils/EnumerableUtils.cs +++ b/csharp/Lib/Utils/EnumerableUtils.cs @@ -277,6 +277,9 @@ public static class EnumerableUtils public static T[] ToArray(this IEnumerable ts, Int32 n) { + if (ts is T[] ta) + return ta; + var array = new T[n]; var i = 0; @@ -296,6 +299,8 @@ public static class EnumerableUtils return ts as T[] ?? ts.ToArray(ts.Count); } + + public static IEnumerable Concat(this IEnumerable ts, T last) { foreach (var t in ts) diff --git a/csharp/Lib/Utils/StringUtils.cs b/csharp/Lib/Utils/StringUtils.cs index 763a164a0..774706efe 100644 --- a/csharp/Lib/Utils/StringUtils.cs +++ b/csharp/Lib/Utils/StringUtils.cs @@ -132,9 +132,11 @@ public static class StringUtils .SideBySideWith(text, ""); } - public static IReadOnlyList SplitLines(this String s) + public static IReadOnlyList SplitLines(this String? s) { - return s.Split(new[] { Environment.NewLine }, StringSplitOptions.None); + return s is null + ? Array.Empty() + : s.Split(new[] { Environment.NewLine }, StringSplitOptions.None); } diff --git a/csharp/Lib/Utils/TextBlock.cs b/csharp/Lib/Utils/TextBlock.cs index 1f7349d78..15d26e63f 100644 --- a/csharp/Lib/Utils/TextBlock.cs +++ b/csharp/Lib/Utils/TextBlock.cs @@ -8,13 +8,19 @@ public class TextBlock public override String ToString() => _Lines.JoinLines(); - public static TextBlock AlignLeft(IReadOnlyList things) + public static TextBlock Empty { get; } = new TextBlock(); + + public static TextBlock AlignLeft(IEnumerable things) { var lines = things .SelectMany(GetLines) + .Unless(String.IsNullOrEmpty) .ToList(); - var width = lines.Max(l => l.Length); + if (!lines.Any()) + return Empty; + + var width = lines.Max(l => l.Length); var alignedLines = lines .Select(l => l.PadRight(width)) @@ -27,8 +33,12 @@ public class TextBlock { var lines = things .SelectMany(GetLines) + .Unless(String.IsNullOrEmpty) .ToList(); + if (!lines.Any()) + return Empty; + var width = lines.Max(l => l.Length); var alignedLines = lines @@ -42,8 +52,12 @@ public class TextBlock { var lines = things .SelectMany(GetLines) + .Where(l => !String.IsNullOrEmpty(l)) .ToList(); + if (!lines.Any()) + return Empty; + var width = lines.Max(l => l.Length); var alignedLines = lines @@ -52,15 +66,17 @@ public class TextBlock return new TextBlock(alignedLines); } - - public static TextBlock AlignTop(IReadOnlyList things) { var columns = things .Select(GetLines) + .Where(c => c.Count > 0) .ToList(); + if (!columns.Any()) + return Empty; + var height = columns.Max(l => l.Count); var alignedLines = Enumerable @@ -76,8 +92,12 @@ public class TextBlock { var columns = things .Select(GetLines) + .Where(c => c.Count > 0) .ToList(); + if (!columns.Any()) + return Empty; + var height = columns.Max(l => l.Count); var alignedLines = Enumerable @@ -93,8 +113,12 @@ public class TextBlock { var columns = things .Select(GetLines) + .Where(c => c.Count > 0) .ToList(); + if (!columns.Any()) + return Empty; + var height = columns.Max(l => l.Count); var alignedLines = Enumerable @@ -105,18 +129,18 @@ public class TextBlock return new TextBlock(alignedLines); } - public static TextBlock AlignLeft (params Object[] things) => AlignLeft ((IReadOnlyList) things); - public static TextBlock AlignRight (params Object[] things) => AlignRight ((IReadOnlyList) things); - public static TextBlock AlignTop (params Object[] things) => AlignTop ((IReadOnlyList) things); - public static TextBlock AlignBottom (params Object[] things) => AlignBottom ((IReadOnlyList) things); - public static TextBlock AlignCenterVertical (params Object[] things) => AlignCenterVertical ((IReadOnlyList) things); - public static TextBlock AlignCenterHorizontal(params Object[] things) => AlignCenterHorizontal((IReadOnlyList) things); + public static TextBlock AlignLeft (params Object?[] things) => AlignLeft ((IReadOnlyList) things); + public static TextBlock AlignRight (params Object?[] things) => AlignRight ((IReadOnlyList) things); + public static TextBlock AlignTop (params Object?[] things) => AlignTop ((IReadOnlyList) things); + public static TextBlock AlignBottom (params Object?[] things) => AlignBottom ((IReadOnlyList) things); + public static TextBlock AlignCenterVertical (params Object?[] things) => AlignCenterVertical ((IReadOnlyList) things); + public static TextBlock AlignCenterHorizontal(params Object?[] things) => AlignCenterHorizontal((IReadOnlyList) things); public static TextBlock FromString(String thing) => AlignLeft(thing); public TextBlock Box() { - var width = _Lines.Max(l => l.Length); + var width = _Lines.Any() ? _Lines.Max(l => l.Length) : 0; var hLine = "".PadRight(width + 2, '─'); var top = "┌" + hLine + "┐"; @@ -134,7 +158,7 @@ public class TextBlock public TextBlock TitleBox(String title) { - var linesWidth = _Lines.Max(l => l.Length); + var linesWidth = _Lines.Any() ? _Lines.Max(l => l.Length) : 0; var titleWidth = title.Length; var width = Math.Max(linesWidth, titleWidth); @@ -175,15 +199,18 @@ public class TextBlock } - private static IReadOnlyList GetLines(Object t) + private static IReadOnlyList GetLines(Object? t) { - return t is TextBlock tb - ? tb._Lines - : t.ToString()!.SplitLines(); + return t switch + { + TextBlock tb => tb._Lines, + null => Array.Empty(), + _ => t.ToString()!.SplitLines() + }; } private static String Space(Int32 totalWidth) { return "".PadRight(totalWidth); } -} +} \ No newline at end of file diff --git a/csharp/Lib/Utils/Utils.cs b/csharp/Lib/Utils/Utils.cs index 5fa0c4a12..40b7be82f 100644 --- a/csharp/Lib/Utils/Utils.cs +++ b/csharp/Lib/Utils/Utils.cs @@ -60,9 +60,15 @@ public static class Utils return t; } + // Below does not work ;( + // [DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)] + // public static R Apply(this T t, Func f) where T : S + // { + // return f(t); + // } + [DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)] public static R Apply(this T t, Func f) => f(t); - [DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)] public static R Apply(this (T1 p1, T2 p2) t, Func f) => f(t.p1, t.p2); diff --git a/rust/VrmGrabberOxidised/Cargo.lock b/rust/VrmGrabberOxidised/Cargo.lock new file mode 100644 index 000000000..e4878cddd --- /dev/null +++ b/rust/VrmGrabberOxidised/Cargo.lock @@ -0,0 +1,2020 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "VrmGrabberOxidised" +version = "0.1.0" +dependencies = [ + "handlebars", + "openssl", + "reqwest", + "rocket", + "serde", + "serde_json", + "urlencoding", +] + +[[package]] +name = "addr2line" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +dependencies = [ + "memchr", +] + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-trait" +version = "0.1.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atomic" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" + +[[package]] +name = "binascii" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cookie" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "cpufeatures" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "devise" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6eacefd3f541c66fc61433d65e54e0e46e0a029a819a7dbbc7a7b489e8a85f8" +dependencies = [ + "devise_codegen", + "devise_core", +] + +[[package]] +name = "devise_codegen" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8cf4b8dd484ede80fd5c547592c46c3745a617c8af278e2b72bea86b2dfed6" +dependencies = [ + "devise_core", + "quote", +] + +[[package]] +name = "devise_core" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35b50dba0afdca80b187392b24f2499a88c336d5a8493e4b4ccfb608708be56a" +dependencies = [ + "bitflags 2.3.3", + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "encoding_rs" +version = "0.8.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "fastrand" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" + +[[package]] +name = "figment" +version = "0.10.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4547e226f4c9ab860571e070a9034192b3175580ecea38da34fcdb53a018c9a5" +dependencies = [ + "atomic", + "pear", + "serde", + "toml", + "uncased", + "version_check", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generator" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "windows", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "h2" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 1.9.3", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "handlebars" +version = "5.0.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222fb09c16263df5bb041ad90090f377aaee0e2442bcf21eefa76e46325a36f5" +dependencies = [ + "log", + "pest", + "pest_derive", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + +[[package]] +name = "hermit-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", +] + +[[package]] +name = "inlinable_string" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" + +[[package]] +name = "ipnet" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" + +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "linux-raw-sys" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" + +[[package]] +name = "lock_api" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" + +[[package]] +name = "loom" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "multer" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http", + "httparse", + "log", + "memchr", + "mime", + "spin", + "tokio", + "tokio-util", + "version_check", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "openssl" +version = "0.10.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-src" +version = "111.26.0+1.1.1u" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efc62c9f12b22b8f5208c23a7200a442b2e5999f8bdf80233852122b5a4f6f37" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" +dependencies = [ + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "pear" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a386cd715229d399604b50d1361683fe687066f42d56f54be995bc6868f71c" +dependencies = [ + "inlinable_string", + "pear_codegen", + "yansi 1.0.0-rc", +] + +[[package]] +name = "pear_codegen" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f0f13dac8069c139e8300a6510e3f4143ecf5259c60b116a9b271b4ca0d54" +dependencies = [ + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "pest" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d2d1d55045829d65aad9d389139882ad623b33b904e7c9f1b10c5b8927298e5" +dependencies = [ + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f94bca7e7a599d89dea5dfa309e217e7906c3c007fb9c3299c40b10d6a315d3" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d490fe7e8556575ff6911e45567ab95e71617f43781e5c05490dc8d75c965c" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pest_meta" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2674c66ebb4b4d9036012091b537aae5878970d6999f81a265034d85b136b341" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "version_check", + "yansi 1.0.0-rc", +] + +[[package]] +name = "quote" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "ref-cast" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61ef7e18e8841942ddb1cf845054f8008410030a3997875d9e49b7a363063df1" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfaf0c85b766276c797f3791f5bc6d5bd116b41d53049af2789666b0c0bc9fa" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "regex" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.3.3", + "regex-syntax 0.7.4", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.7.4", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" + +[[package]] +name = "reqwest" +version = "0.11.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "rocket" +version = "0.5.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58734f7401ae5cfd129685b48f61182331745b357b96f2367f01aebaf1cc9cc9" +dependencies = [ + "async-stream", + "async-trait", + "atomic", + "binascii", + "bytes", + "either", + "figment", + "futures", + "indexmap 1.9.3", + "is-terminal", + "log", + "memchr", + "multer", + "num_cpus", + "parking_lot", + "pin-project-lite", + "rand", + "ref-cast", + "rocket_codegen", + "rocket_http", + "serde", + "state", + "tempfile", + "time", + "tokio", + "tokio-stream", + "tokio-util", + "ubyte", + "version_check", + "yansi 0.5.1", +] + +[[package]] +name = "rocket_codegen" +version = "0.5.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7093353f14228c744982e409259fb54878ba9563d08214f2d880d59ff2fc508b" +dependencies = [ + "devise", + "glob", + "indexmap 1.9.3", + "proc-macro2", + "quote", + "rocket_http", + "syn", + "unicode-xid", +] + +[[package]] +name = "rocket_http" +version = "0.5.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936012c99162a03a67f37f9836d5f938f662e26f2717809761a9ac46432090f4" +dependencies = [ + "cookie", + "either", + "futures", + "http", + "hyper", + "indexmap 1.9.3", + "log", + "memchr", + "pear", + "percent-encoding", + "pin-project-lite", + "ref-cast", + "serde", + "smallvec", + "stable-pattern", + "state", + "time", + "tokio", + "uncased", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustix" +version = "0.38.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +dependencies = [ + "bitflags 2.3.3", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.176" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76dc28c9523c5d70816e393136b86d48909cfb27cecaa902d338c19ed47164dc" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.176" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e7b8c5dc823e3b90651ff1d3808419cd14e5ad76de04feaf37da114e7a306f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "stable-pattern" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4564168c00635f88eaed410d5efa8131afa8d8699a612c80c455a0ba05c21045" +dependencies = [ + "memchr", +] + +[[package]] +name = "state" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbe866e1e51e8260c9eed836a042a5e7f6726bb2b411dffeaa712e19c388f23b" +dependencies = [ + "loom", +] + +[[package]] +name = "syn" +version = "2.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys", +] + +[[package]] +name = "thiserror" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" +dependencies = [ + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" + +[[package]] +name = "time-macros" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" +dependencies = [ + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" +dependencies = [ + "autocfg", + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +dependencies = [ + "indexmap 2.0.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "ubyte" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c81f0dae7d286ad0d9366d7679a77934cfc3cf3a8d67e82669794412b2368fe6" +dependencies = [ + "serde", +] + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "uncased" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b9bc53168a4be7402ab86c3aad243a84dd7381d09be0eddc81280c1da95ca68" +dependencies = [ + "serde", + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "url" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "winnow" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25b5872fa2e10bd067ae946f927e726d7d603eaeb6e02fa6a350e0722d2b8c11" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "yansi" +version = "1.0.0-rc" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ee746ad3851dd3bc40e4a028ab3b00b99278d929e48957bcb2d111874a7e43e" diff --git a/rust/VrmGrabberOxidised/Cargo.toml b/rust/VrmGrabberOxidised/Cargo.toml new file mode 100644 index 000000000..c89cd3b34 --- /dev/null +++ b/rust/VrmGrabberOxidised/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "VrmGrabberOxidised" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rocket = "=0.5.0-rc.3" +reqwest = "0.11.18" +openssl = { version = "0.10", features = ["vendored"]} +serde = {version = "1.0.173", features = ["derive"]} +serde_json = "1.0.103" +handlebars = "5.0.0-beta.1" +urlencoding = "2.1.2" \ No newline at end of file diff --git a/rust/VrmGrabberOxidised/src/installation.rs b/rust/VrmGrabberOxidised/src/installation.rs new file mode 100644 index 000000000..97f1afd2b --- /dev/null +++ b/rust/VrmGrabberOxidised/src/installation.rs @@ -0,0 +1,11 @@ +pub struct Installation { + name: String, + vrm: i64, + ip: String, + identifier: String, + serial: String, + online: String, + last_seen: String, + number_of_batteries: String, + batter_firmware_version: String +} \ No newline at end of file diff --git a/rust/VrmGrabberOxidised/src/main.rs b/rust/VrmGrabberOxidised/src/main.rs new file mode 100644 index 000000000..a6f7db8bd --- /dev/null +++ b/rust/VrmGrabberOxidised/src/main.rs @@ -0,0 +1,168 @@ +use rocket::serde; +use handlebars::Handlebars; +// use rocket::serde::__private::de::TagContentOtherField::Content; + +use urlencoding::encode; + +mod installation; +mod vrm_account; + + +struct InstallationToHtmlInterface<'a> { + Name: &'a str, + Ip: i64, + Vrm: &'a str, + Identifier: &'a str, + Serial: &'a str, + EscapedName: &'a str, + Online: &'a str, + LastSeen: &'a str, + NumBatteries: &'a str, + BatteryVersion: &'a str, + ServerIp : &'a str, + FirmwareVersion: &'a str, +} + +// impl Default for InstallationToHtmlInterface{ +// fn default() -> Self { +// Self{ +// Name: "", +// Ip: 0, +// Vrm: "", +// Identifier: "", +// Serial: "", +// EscapedName: "", +// Online: "", +// LastSeen: "", +// NumBatteries: "", +// BatteryVersion: "", +// ServerIp : "10.2.0.1", +// FirmwareVersion: "AF09", +// } +// } +// } + + +#[macro_use] extern crate rocket; + +#[get("/")] +async fn index() -> String{ + let res = vrm_account::all_installations_request().await; + let json = rocket::serde::Deserialize(res.unwrap().text().await.unwrap()); + let source = " + + +
+ + + + + + + + + + + + + + + {{#inst}} + {{> installations}} + {{/inst}} + +
NameGuiVRMGrafanaIdentifierLast SeenSerial#BatteriesFirmware-VersionUpdate
+
"; + + let partialSource= "{{Name}} + {{online}} {{Ip}} + VRM + Grafana + {{Identifier}} + {{LastSeen}} + {{Serial}} + {{NumBatteries}} + {{BatteryVersion}} + ⬆️{{FirmwareVersion}} + "; + + let mut handlebars = Handlebars::new(); + handlebars.register_template_string("installations", partialSource); + + let mut installsForHtml = Vec::::new(); + for inst in json["records"] { + let mut installation = InstallationToHtmlInterface { + Name: inst["name"], + Ip: 0, // TODO + Vrm: inst["idSite"].parse::(), + Identifier: inst["identifier"], + Serial: "", //Todo Grab and parse Details + EscapedName: &encode(inst["name"]).to_string(), + Online: "", + LastSeen: "", + NumBatteries: "", + BatteryVersion: "", + ServerIp : "10.2.0.1", + FirmwareVersion: "AF09", + }; + installsForHtml.push(installation) + } + let mut data = installsForHtml; + + let result = handlebars.render(source, &data); + return result.unwrap(); +} + +#[launch] +fn rocket() -> _ { + rocket::build().mount("/", routes![index]) +} \ No newline at end of file diff --git a/rust/VrmGrabberOxidised/src/vrm_account.rs b/rust/VrmGrabberOxidised/src/vrm_account.rs new file mode 100644 index 000000000..eb1c6d854 --- /dev/null +++ b/rust/VrmGrabberOxidised/src/vrm_account.rs @@ -0,0 +1,21 @@ +use std::ops::Add; +use reqwest::{Error, Response}; +// use serde::{Deserialize, Serialize}; + + +const API_ROOT:&str ="https://vrmapi.victronenergy.com/v2"; +const USER_ID:&str = "55450"; +const TOKEN:&str = "88b36e7226ff7fa7bf231d0f9f98e916f661923c84e494cd27b6bc795ec0074b"; + +pub async fn all_installations_request() -> Result { + // use reqwest::header::AUTHORIZATION; + let client = reqwest::Client::new(); + let res = client + .get(API_ROOT.to_owned().add("/users/").add(USER_ID).add("/installations")) + .header("Content-Type", "application/json") + .header("x-authorization","Token ".to_owned()+TOKEN) + .send() + .await; + return res; +} + diff --git a/typescript/Frontend/src/config/axiosConfig.tsx b/typescript/Frontend/src/config/axiosConfig.tsx index 8d9277190..9b47c3c8a 100644 --- a/typescript/Frontend/src/config/axiosConfig.tsx +++ b/typescript/Frontend/src/config/axiosConfig.tsx @@ -1,11 +1,11 @@ import axios from "axios"; export const axiosConfigWithoutToken = axios.create({ - baseURL: "http://localhost:5000/api", + baseURL: "https://localhost:7087", }); const axiosConfig = axios.create({ - baseURL: "http://localhost:5000/api", + baseURL: "https://localhost:7087", }); axiosConfig.defaults.params = {};