fix merge conflict
This commit is contained in:
commit
9e9a899f8e
|
@ -7,9 +7,6 @@ namespace InnovEnergy.App.Backend;
|
||||||
|
|
||||||
public static class Program
|
public static class Program
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void Main(String[] args)
|
public static void Main(String[] args)
|
||||||
{
|
{
|
||||||
//Db.CreateFakeRelations();
|
//Db.CreateFakeRelations();
|
||||||
|
|
Binary file not shown.
|
@ -9,8 +9,9 @@ set -e
|
||||||
|
|
||||||
echo -e "\n============================ Build ============================\n"
|
echo -e "\n============================ Build ============================\n"
|
||||||
|
|
||||||
dotnet publish \
|
dotnet publish \
|
||||||
./SaliMax.csproj \
|
./SaliMax.csproj \
|
||||||
|
-p:PublishTrimmed=false \
|
||||||
-c Release \
|
-c Release \
|
||||||
-r linux-x64
|
-r linux-x64
|
||||||
|
|
||||||
|
|
|
@ -30,11 +30,17 @@ public static class Controller
|
||||||
mode.WriteLine();
|
mode.WriteLine();
|
||||||
|
|
||||||
if (mode is EssMode.Off or EssMode.NoGridMeter)
|
if (mode is EssMode.Off or EssMode.NoGridMeter)
|
||||||
return new EssControl(mode, EssLimit.NoLimit, PowerCorrection: 0, PowerSetpoint: 0);
|
return EssControl.Default;
|
||||||
|
|
||||||
var essDelta = s.ComputePowerDelta(mode);
|
var essDelta = s.ComputePowerDelta(mode);
|
||||||
|
|
||||||
var unlimitedControl = new EssControl(mode, EssLimit.NoLimit, essDelta, 0);
|
var unlimitedControl = new EssControl
|
||||||
|
{
|
||||||
|
Mode = mode,
|
||||||
|
LimitedBy = EssLimit.NoLimit,
|
||||||
|
PowerCorrection = essDelta,
|
||||||
|
PowerSetpoint = 0
|
||||||
|
};
|
||||||
|
|
||||||
var limitedControl = unlimitedControl
|
var limitedControl = unlimitedControl
|
||||||
.LimitChargePower(s)
|
.LimitChargePower(s)
|
||||||
|
|
|
@ -3,13 +3,21 @@ using InnovEnergy.Lib.Units.Power;
|
||||||
namespace InnovEnergy.App.SaliMax.Ess;
|
namespace InnovEnergy.App.SaliMax.Ess;
|
||||||
|
|
||||||
public record EssControl
|
public record EssControl
|
||||||
(
|
|
||||||
EssMode Mode,
|
|
||||||
EssLimit LimitedBy,
|
|
||||||
ActivePower PowerCorrection,
|
|
||||||
ActivePower PowerSetpoint
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
|
public required EssMode Mode { get; init; }
|
||||||
|
public required EssLimit LimitedBy { get; init; }
|
||||||
|
public required ActivePower PowerCorrection { get; init; }
|
||||||
|
public required ActivePower PowerSetpoint { get; init; }
|
||||||
|
|
||||||
|
public static EssControl Default { get; } = new()
|
||||||
|
{
|
||||||
|
Mode = EssMode.Off,
|
||||||
|
LimitedBy = EssLimit.NoLimit,
|
||||||
|
PowerCorrection = 0,
|
||||||
|
PowerSetpoint = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
public EssControl LimitChargePower(Double controlDelta, EssLimit reason)
|
public EssControl LimitChargePower(Double controlDelta, EssLimit reason)
|
||||||
{
|
{
|
||||||
var overload = PowerCorrection - controlDelta;
|
var overload = PowerCorrection - controlDelta;
|
||||||
|
|
|
@ -12,20 +12,20 @@ namespace InnovEnergy.App.SaliMax.Ess;
|
||||||
|
|
||||||
public record StatusRecord
|
public record StatusRecord
|
||||||
{
|
{
|
||||||
public AcDcDevicesRecord AcDc { get; init; } = null!;
|
public required AcDcDevicesRecord AcDc { get; init; }
|
||||||
public DcDcDevicesRecord DcDc { get; init; } = null!;
|
public required DcDcDevicesRecord DcDc { get; init; }
|
||||||
public Battery48TlRecords Battery { get; init; } = null!;
|
public required Battery48TlRecords Battery { get; init; }
|
||||||
public EmuMeterRegisters? GridMeter { get; init; }
|
public required EmuMeterRegisters? GridMeter { get; init; }
|
||||||
public EmuMeterRegisters? LoadOnAcIsland { get; init; }
|
public required EmuMeterRegisters? LoadOnAcIsland { get; init; }
|
||||||
public AcPowerDevice? LoadOnAcGrid { get; init; } = null!;
|
public required AcPowerDevice? LoadOnAcGrid { get; init; }
|
||||||
public AcPowerDevice? PvOnAcGrid { get; init; } = null!;
|
public required AcPowerDevice? PvOnAcGrid { get; init; }
|
||||||
public AcPowerDevice? PvOnAcIsland { get; init; } = null!;
|
public required AcPowerDevice? PvOnAcIsland { get; init; }
|
||||||
public AcPowerDevice? AcGridToAcIsland { get; init; } = null!;
|
public required AcPowerDevice? AcGridToAcIsland { get; init; }
|
||||||
public DcPowerDevice? LoadOnDc { get; init; } = null!;
|
public required DcPowerDevice? LoadOnDc { get; init; }
|
||||||
public RelaysRecord? Relays { get; init; }
|
public required RelaysRecord? Relays { get; init; }
|
||||||
public AmptStatus PvOnDc { get; init; } = null!;
|
public required AmptStatus PvOnDc { get; init; }
|
||||||
public Config Config { get; init; } = null!;
|
public required Config Config { get; init; }
|
||||||
public EssControl EssControl { get; set; } = null!;
|
public required EssControl EssControl { get; set; } // TODO: init only
|
||||||
public StateMachine StateMachine { get; } = new StateMachine();
|
public required StateMachine StateMachine { get; init; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ public static class Flow
|
||||||
|
|
||||||
public static TextBlock Horizontal(Unit amount, Int32 width = 10)
|
public static TextBlock Horizontal(Unit amount, Int32 width = 10)
|
||||||
{
|
{
|
||||||
var label = amount.ToStringRounded();
|
var label = amount.ToDisplayString();
|
||||||
var arrowChar = amount.Value < 0 ? LeftArrowChar : RightArrowChar;
|
var arrowChar = amount.Value < 0 ? LeftArrowChar : RightArrowChar;
|
||||||
var arrow = Enumerable.Repeat(arrowChar, width).Join();
|
var arrow = Enumerable.Repeat(arrowChar, width).Join();
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ public static class Flow
|
||||||
[SuppressMessage("ReSharper", "CoVariantArrayConversion")]
|
[SuppressMessage("ReSharper", "CoVariantArrayConversion")]
|
||||||
public static TextBlock Vertical(Unit amount, Int32 height = 4)
|
public static TextBlock Vertical(Unit amount, Int32 height = 4)
|
||||||
{
|
{
|
||||||
var label = amount.ToStringRounded();
|
var label = amount.ToDisplayString();
|
||||||
var arrowChar = amount.Value < 0 ? UpArrowChar : DownArrowChar;
|
var arrowChar = amount.Value < 0 ? UpArrowChar : DownArrowChar;
|
||||||
var halfArrow = Enumerable.Repeat(arrowChar, height/2);
|
var halfArrow = Enumerable.Repeat(arrowChar, height/2);
|
||||||
|
|
||||||
|
|
|
@ -148,7 +148,9 @@ internal static class Program
|
||||||
LoadOnAcIsland = loadOnAcIsland,
|
LoadOnAcIsland = loadOnAcIsland,
|
||||||
LoadOnDc = loadOnDc,
|
LoadOnDc = loadOnDc,
|
||||||
|
|
||||||
Config = Config.Load() // load from disk every iteration, so config can be changed while running
|
StateMachine = StateMachine.Default,
|
||||||
|
EssControl = EssControl.Default,
|
||||||
|
Config = Config.Load() // load from disk every iteration, so config can be changed while running
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,17 +230,17 @@ internal static class Program
|
||||||
var islandToGridBusPower = inverterPower + islandLoadPower;
|
var islandToGridBusPower = inverterPower + islandLoadPower;
|
||||||
var gridLoadPower = s.LoadOnAcGrid is null ? 0: s.LoadOnAcGrid.Power.Active;
|
var gridLoadPower = s.LoadOnAcGrid is null ? 0: s.LoadOnAcGrid.Power.Active;
|
||||||
|
|
||||||
var gridPowerByPhase = TextBlock.AlignLeft(s.GridMeter.Ac.L1.Power.Active.ToStringRounded(),
|
var gridPowerByPhase = TextBlock.AlignLeft(s.GridMeter.Ac.L1.Power.Active.ToDisplayString(),
|
||||||
s.GridMeter.Ac.L2.Power.Active.ToStringRounded(),
|
s.GridMeter.Ac.L2.Power.Active.ToDisplayString(),
|
||||||
s.GridMeter.Ac.L3.Power.Active.ToStringRounded());
|
s.GridMeter.Ac.L3.Power.Active.ToDisplayString());
|
||||||
|
|
||||||
var gridVoltageByPhase = TextBlock.AlignLeft(s.GridMeter.Ac.L1.Voltage.ToStringRounded(),
|
var gridVoltageByPhase = TextBlock.AlignLeft(s.GridMeter.Ac.L1.Voltage.ToDisplayString(),
|
||||||
s.GridMeter.Ac.L2.Voltage.ToStringRounded(),
|
s.GridMeter.Ac.L2.Voltage.ToDisplayString(),
|
||||||
s.GridMeter.Ac.L3.Voltage.ToStringRounded());
|
s.GridMeter.Ac.L3.Voltage.ToDisplayString());
|
||||||
|
|
||||||
var inverterPowerByPhase = TextBlock.AlignLeft(s.AcDc.Ac.L1.Power.Active.ToStringRounded(),
|
var inverterPowerByPhase = TextBlock.AlignLeft(s.AcDc.Ac.L1.Power.Active.ToDisplayString(),
|
||||||
s.AcDc.Ac.L2.Power.Active.ToStringRounded(),
|
s.AcDc.Ac.L2.Power.Active.ToDisplayString(),
|
||||||
s.AcDc.Ac.L3.Power.Active.ToStringRounded());
|
s.AcDc.Ac.L3.Power.Active.ToDisplayString());
|
||||||
|
|
||||||
// ReSharper disable once CoVariantArrayConversion
|
// ReSharper disable once CoVariantArrayConversion
|
||||||
var inverterPowerByAcDc = TextBlock.AlignLeft(s.AcDc.Devices
|
var inverterPowerByAcDc = TextBlock.AlignLeft(s.AcDc.Devices
|
||||||
|
@ -246,7 +248,7 @@ internal static class Program
|
||||||
.ToArray());
|
.ToArray());
|
||||||
|
|
||||||
var dcLinkVoltage = TextBlock.CenterHorizontal("",
|
var dcLinkVoltage = TextBlock.CenterHorizontal("",
|
||||||
s.DcDc.Dc.Link.Voltage.ToStringRounded(),
|
s.DcDc.Dc.Link.Voltage.ToDisplayString(),
|
||||||
"");
|
"");
|
||||||
|
|
||||||
//var inverterPowerByPhase = new ActivePower[(Int32)s.AcDc.Ac.L1.Power.Active, (Int32)s.AcDc.Ac.L2.Power.Active, (Int32)s.AcDc.Ac.L3.Power.Active];
|
//var inverterPowerByPhase = new ActivePower[(Int32)s.AcDc.Ac.L1.Power.Active, (Int32)s.AcDc.Ac.L2.Power.Active, (Int32)s.AcDc.Ac.L3.Power.Active];
|
||||||
|
@ -273,7 +275,7 @@ internal static class Program
|
||||||
var gridBox = TextBlock.AlignLeft(gridPowerByPhase).TitleBox("Grid");
|
var gridBox = TextBlock.AlignLeft(gridPowerByPhase).TitleBox("Grid");
|
||||||
var inverterBox = TextBlock.AlignLeft(inverterPowerByAcDc).TitleBox("Inverter");
|
var inverterBox = TextBlock.AlignLeft(inverterPowerByAcDc).TitleBox("Inverter");
|
||||||
var dcDcBox = TextBlock.AlignLeft(dc48Voltage).TitleBox("DC/DC");
|
var dcDcBox = TextBlock.AlignLeft(dc48Voltage).TitleBox("DC/DC");
|
||||||
var batteryBox = TextBlock.AlignLeft(batteryVoltage.ToStringRounded(), batterySoc.ToStringRounded(), batteryCurrent.ToStringRounded(), batteryTemp.ToStringRounded()).TitleBox("Battery");
|
var batteryBox = TextBlock.AlignLeft(batteryVoltage.ToDisplayString(), batterySoc.ToDisplayString(), batteryCurrent.ToDisplayString(), batteryTemp.ToDisplayString()).TitleBox("Battery");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,12 +9,12 @@ namespace InnovEnergy.App.SaliMax;
|
||||||
|
|
||||||
public record S3Config
|
public record S3Config
|
||||||
{
|
{
|
||||||
public String Bucket { get; init; } = "";
|
public required String Bucket { get; init; }
|
||||||
public String Region { get; init; } = "";
|
public required String Region { get; init; }
|
||||||
public String Provider { get; init; } = "";
|
public required String Provider { get; init; }
|
||||||
public String Key { get; init; } = "";
|
public required String Key { get; init; }
|
||||||
public String Secret { get; init; } = "";
|
public required String Secret { get; init; }
|
||||||
public String ContentType { get; init; } = "";
|
public required String ContentType { get; init; }
|
||||||
|
|
||||||
public String Host => $"{Bucket}.{Region}.{Provider}";
|
public String Host => $"{Bucket}.{Region}.{Provider}";
|
||||||
public String Url => $"https://{Host}";
|
public String Url => $"https://{Host}";
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
namespace InnovEnergy.App.SaliMax.System;
|
namespace InnovEnergy.App.SaliMax.System;
|
||||||
|
|
||||||
public class StateMachine
|
public record StateMachine
|
||||||
{
|
{
|
||||||
public String Message { get; set; } = "Panic: Unknown State!";
|
public required String Message { get; set; } // TODO: init only
|
||||||
public Int32 State { get; set; } = 100;
|
public required Int32 State { get; set; } // TODO: init only
|
||||||
|
|
||||||
|
public static StateMachine Default { get; } = new StateMachine { State = 100, Message = "Unknown State" };
|
||||||
}
|
}
|
|
@ -6,13 +6,15 @@
|
||||||
<LangVersion>preview</LangVersion>
|
<LangVersion>preview</LangVersion>
|
||||||
<IsTrimmable>true</IsTrimmable>
|
<IsTrimmable>true</IsTrimmable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<InvariantGlobalization>true</InvariantGlobalization>
|
<InvariantGlobalization>true</InvariantGlobalization>
|
||||||
<SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
|
<SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
|
||||||
<RootNamespace>$([System.Text.RegularExpressions.Regex]::Match($(MSBuildProjectExtensionsPath), "[/\\]csharp[/\\].*[/\\]obj").ToString().Replace("/",".").Replace("\\",".").Replace(".csharp", $(Company)).Replace(".obj", ""))</RootNamespace>
|
<RootNamespace>Please.reload.the.project.Rider.is.stupid</RootNamespace>
|
||||||
<Authors>$(Company) Team</Authors>
|
<Authors>$(Company) Team</Authors>
|
||||||
<!-- <ProjectPath>$([System.Text.RegularExpressions.Regex]::Match($(MSBuildProjectExtensionsPath), "[/\\]csharp[/\\].*[/\\]obj").ToString().Replace("/",".").Replace("\\",".").Replace(".csharp", $(Company)).Replace(".obj", ""))</ProjectPath>-->
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(SolutionDir)' != ''">
|
||||||
|
<RootNamespace>$(Company).$(MSBuildProjectDirectory.Replace($(SolutionDir), "").Replace("/",".").Replace("\","."))</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
|
@ -4,8 +4,8 @@ namespace InnovEnergy.Lib.Channels.Stages;
|
||||||
|
|
||||||
public class Channel<Tx, Rx>
|
public class Channel<Tx, Rx>
|
||||||
{
|
{
|
||||||
public AsyncAction<Tx> Write { get; init; } = _ => throw new NotImplementedException(nameof(Write));
|
public required AsyncAction<Tx> Write { get; init; }
|
||||||
public Async<Rx> Read { get; init; } = () => throw new NotImplementedException(nameof(Read));
|
public required Async<Rx> Read { get; init; }
|
||||||
|
|
||||||
public Channel<T, R> Map<T, R>(Stage<T, Tx, Rx, R> stage)
|
public Channel<T, R> Map<T, R>(Stage<T, Tx, Rx, R> stage)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,9 +4,9 @@ namespace InnovEnergy.Lib.Channels.Stages;
|
||||||
|
|
||||||
public class ConnectedChannel<Tx, Rx> : Channel<Tx,Rx>, IAsyncDisposable
|
public class ConnectedChannel<Tx, Rx> : Channel<Tx,Rx>, IAsyncDisposable
|
||||||
{
|
{
|
||||||
public Func<Boolean> IsOpen { get; init; } = () => throw new NotImplementedException(nameof(IsOpen));
|
public required Func<Boolean> IsOpen { get; init; }
|
||||||
public AsyncAction Open { get; init; } = () => throw new NotImplementedException(nameof(Open));
|
public required AsyncAction Open { get; init; }
|
||||||
public AsyncAction Close { get; init; } = () => throw new NotImplementedException(nameof(Close));
|
public required AsyncAction Close { get; init; }
|
||||||
|
|
||||||
public async ValueTask DisposeAsync() => await Close();
|
public async ValueTask DisposeAsync() => await Close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
namespace InnovEnergy.Lib.Devices.AMPT;
|
namespace InnovEnergy.Lib.Devices.AMPT;
|
||||||
|
|
||||||
|
|
||||||
|
// not used ATM
|
||||||
public class AmptCommunicationUnitStatus
|
public class AmptCommunicationUnitStatus
|
||||||
{
|
{
|
||||||
public UInt32 Sid { get; init; } // A well-known value 0x53756e53, uniquely identifies this as a SunSpec Modbus Map
|
public required UInt32 Sid { get; init; } // A well-known value 0x53756e53, uniquely identifies this as a SunSpec Modbus Map
|
||||||
public UInt16 IdSunSpec { get; init; } // A well-known value 1, uniquely identifies this as a SunSpec Common Model
|
public required UInt16 IdSunSpec { get; init; } // A well-known value 1, uniquely identifies this as a SunSpec Common Model
|
||||||
|
|
||||||
public String Manufacturer { get; init; } = "undefined"; // A well-known value registered with SunSpec for compliance: "Ampt"
|
public required String Manufacturer { get; init; } // A well-known value registered with SunSpec for compliance: "Ampt"
|
||||||
public String Model { get; init; } = "undefined"; // Manufacturer specific value "Communication Unit"
|
public required String Model { get; init; } // Manufacturer specific value "Communication Unit"
|
||||||
public String Version { get; init; } = "undefined"; // Software Version
|
public required String Version { get; init; } // Software Version
|
||||||
public String SerialNumber { get; init; } = "undefined"; // Manufacturer specific value
|
public required String SerialNumber { get; init; } // Manufacturer specific value
|
||||||
public Int16 DeviceAddress { get; init; } // Modbus Device ID
|
public required Int16 DeviceAddress { get; init; } // Modbus Device ID
|
||||||
public UInt16 IdVendor { get; init; } // Ampt SunSpec Vendor Code 64050
|
public required UInt16 IdVendor { get; init; } // Ampt SunSpec Vendor Code 64050
|
||||||
|
|
||||||
public IReadOnlyList<AmptStatus> Devices { get; init; } = Array.Empty<AmptStatus>();
|
public required IReadOnlyList<AmptStatus> Devices { get; init; }
|
||||||
}
|
}
|
|
@ -21,13 +21,13 @@ public interface IMatchRule
|
||||||
|
|
||||||
public record MatchRule : IMatchRule
|
public record MatchRule : IMatchRule
|
||||||
{
|
{
|
||||||
public MessageType? Type { get; init; } = default;
|
public MessageType? Type { get; init; }
|
||||||
public String? Interface { get; init; } = default;
|
public String? Interface { get; init; }
|
||||||
public String? Member { get; init; } = default;
|
public String? Member { get; init; }
|
||||||
public ObjectPath? Path { get; init; } = default;
|
public ObjectPath? Path { get; init; }
|
||||||
public ObjectPath? PathNamespace { get; init; } = default;
|
public ObjectPath? PathNamespace { get; init; }
|
||||||
public String? Sender { get; init; } = default;
|
public String? Sender { get; init; }
|
||||||
public String? Destination { get; init; } = default;
|
public String? Destination { get; init; }
|
||||||
public Boolean Eavesdrop { get; init; } = false;
|
public Boolean Eavesdrop { get; init; } = false;
|
||||||
|
|
||||||
public override String ToString() => this.Rule();
|
public override String ToString() => this.Rule();
|
||||||
|
|
|
@ -5,10 +5,10 @@ public sealed class Ac1Bus
|
||||||
private Ac1Bus()
|
private Ac1Bus()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
public Voltage Voltage { get; private init; } = null!;
|
public required Voltage Voltage { get; init; }
|
||||||
public Current Current { get; private init; } = null!;
|
public required Current Current { get; init; }
|
||||||
public AcPower Power { get; private init; } = null!;
|
public required AcPower Power { get; init; }
|
||||||
public Frequency Frequency { get; private init; } = null!;
|
public required Frequency Frequency { get; init; }
|
||||||
|
|
||||||
public static Ac1Bus FromVoltageCurrentFrequencyPhi(Double voltageRms,
|
public static Ac1Bus FromVoltageCurrentFrequencyPhi(Double voltageRms,
|
||||||
Double currentRms,
|
Double currentRms,
|
||||||
|
|
|
@ -6,11 +6,11 @@ public sealed class Ac3Bus
|
||||||
{
|
{
|
||||||
private Ac3Bus() {}
|
private Ac3Bus() {}
|
||||||
|
|
||||||
public AcPhase L1 { get; private init; } = null!;
|
public required AcPhase L1 { get; init; }
|
||||||
public AcPhase L2 { get; private init; } = null!;
|
public required AcPhase L2 { get; init; }
|
||||||
public AcPhase L3 { get; private init; } = null!;
|
public required AcPhase L3 { get; init; }
|
||||||
public AcPower Power { get; private init; } = null!;
|
public required AcPower Power { get; init; }
|
||||||
public Frequency Frequency { get; private init; } = null!;
|
public required Frequency Frequency { get; init; }
|
||||||
|
|
||||||
public static Ac3Bus FromPhasesAndFrequency(AcPhase l1,
|
public static Ac3Bus FromPhasesAndFrequency(AcPhase l1,
|
||||||
AcPhase l2,
|
AcPhase l2,
|
||||||
|
|
|
@ -7,9 +7,9 @@ public sealed class AcPhase
|
||||||
{
|
{
|
||||||
private AcPhase(){}
|
private AcPhase(){}
|
||||||
|
|
||||||
public Voltage Voltage { get; private init; } = null!;
|
public required Voltage Voltage { get; init; }
|
||||||
public Current Current { get; private init; } = null!;
|
public required Current Current { get; init; }
|
||||||
public AcPower Power { get; private init; } = null!;
|
public required AcPower Power { get; init; }
|
||||||
|
|
||||||
public static AcPhase FromVoltageCurrentPhi(Voltage voltageRms,
|
public static AcPhase FromVoltageCurrentPhi(Voltage voltageRms,
|
||||||
Current currentRms,
|
Current currentRms,
|
||||||
|
|
|
@ -8,11 +8,11 @@ public sealed class AcPower
|
||||||
{
|
{
|
||||||
private AcPower(){}
|
private AcPower(){}
|
||||||
|
|
||||||
public ApparentPower Apparent { get; private init; } = null!;
|
public required ApparentPower Apparent { get; init; }
|
||||||
public ActivePower Active { get; private init; } = null!;
|
public required ActivePower Active { get; init; }
|
||||||
public ReactivePower Reactive { get; private init; } = null!;
|
public required ReactivePower Reactive { get; init; }
|
||||||
public Angle Phi { get; private init; } = null!;
|
public required Angle Phi { get; init; }
|
||||||
public Double CosPhi { get; private init; }
|
public required Double CosPhi { get; init; }
|
||||||
|
|
||||||
public static AcPower FromActiveReactiveApparent(ActivePower activePower, ReactivePower reactivePower, ApparentPower apparentPower)
|
public static AcPower FromActiveReactiveApparent(ActivePower activePower, ReactivePower reactivePower, ApparentPower apparentPower)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,9 +6,9 @@ public sealed class DcBus
|
||||||
{
|
{
|
||||||
private DcBus() {}
|
private DcBus() {}
|
||||||
|
|
||||||
public Voltage Voltage { get; private init; } = null!;
|
public required Voltage Voltage { get; init; }
|
||||||
public Current Current { get; private init; } = null!;
|
public required Current Current { get; init; }
|
||||||
public ActivePower Power { get; private init; } = null!;
|
public required ActivePower Power { get; init; }
|
||||||
|
|
||||||
public static DcBus FromVoltageCurrent(Voltage voltage, Current current) => new()
|
public static DcBus FromVoltageCurrent(Voltage voltage, Current current) => new()
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,7 @@ namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
public sealed class Energy : Unit
|
public sealed class Energy : Unit
|
||||||
{
|
{
|
||||||
public override String Symbol => "kWh";
|
public override String Symbol => "Wh";
|
||||||
|
|
||||||
public Energy(Double value) : base(value)
|
public Energy(Double value) : base(value)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,7 +12,6 @@ public sealed class ActivePower : AcPower
|
||||||
public static implicit operator ActivePower(Double d) => new ActivePower(d);
|
public static implicit operator ActivePower(Double d) => new ActivePower(d);
|
||||||
public static implicit operator Double(ActivePower d) => d.Value;
|
public static implicit operator Double(ActivePower d) => d.Value;
|
||||||
|
|
||||||
|
|
||||||
public static ActivePower operator -(ActivePower d) => -d.Value;
|
public static ActivePower operator -(ActivePower d) => -d.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,5 +8,35 @@ public abstract class Unit
|
||||||
public Double Value { get; }
|
public Double Value { get; }
|
||||||
|
|
||||||
public override String ToString() => $"{Value} {Symbol}";
|
public override String ToString() => $"{Value} {Symbol}";
|
||||||
public String ToStringRounded() => $"{Math.Round(Value,3)} {Symbol}";
|
|
||||||
|
public String ToDisplayString()
|
||||||
|
{
|
||||||
|
if (Value == 0)
|
||||||
|
return $"0 {Symbol}";
|
||||||
|
|
||||||
|
var a = Math.Abs(Value);
|
||||||
|
var s = Math.Sign(Value);
|
||||||
|
|
||||||
|
var i = 8;
|
||||||
|
|
||||||
|
while (a >= 10000)
|
||||||
|
{
|
||||||
|
a /= 1000;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
while (a < 10)
|
||||||
|
{
|
||||||
|
a *= 1000;
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
|
||||||
|
var r = a < 100
|
||||||
|
? Math.Floor(a * 10) / 10
|
||||||
|
: Math.Floor(a);
|
||||||
|
|
||||||
|
return $"{r * s} {Prefix[i]}{Symbol}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly IReadOnlyList<String> Prefix = new[] { "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Y" };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Reflection;
|
|
||||||
using InnovEnergy.Lib.Units.Power;
|
using InnovEnergy.Lib.Units.Power;
|
||||||
using InnovEnergy.Lib.Utils;
|
using InnovEnergy.Lib.Utils;
|
||||||
using static System.Reflection.BindingFlags;
|
using static System.Reflection.BindingFlags;
|
||||||
|
@ -20,7 +19,8 @@ public static class Units
|
||||||
public static Frequency Hz (this Double value) => value;
|
public static Frequency Hz (this Double value) => value;
|
||||||
public static Angle Rad (this Double value) => value;
|
public static Angle Rad (this Double value) => value;
|
||||||
public static Temperature Celsius(this Double value) => value;
|
public static Temperature Celsius(this Double value) => value;
|
||||||
public static Energy KWh (this Double value) => value;
|
public static Energy KWh (this Double value) => value * 1000;
|
||||||
|
public static Energy Wh (this Double value) => value;
|
||||||
|
|
||||||
public static String ToCsv(this Object thing)
|
public static String ToCsv(this Object thing)
|
||||||
{
|
{
|
||||||
|
@ -88,87 +88,3 @@ public static class Units
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Prefixes
|
|
||||||
{
|
|
||||||
private static readonly IReadOnlyList<String> Big = new[]
|
|
||||||
{
|
|
||||||
"",
|
|
||||||
"k",
|
|
||||||
"M",
|
|
||||||
"G",
|
|
||||||
"T",
|
|
||||||
"P",
|
|
||||||
"E",
|
|
||||||
"Y",
|
|
||||||
};
|
|
||||||
|
|
||||||
private static readonly IReadOnlyList<String> Small = new[]
|
|
||||||
{
|
|
||||||
"",
|
|
||||||
"m",
|
|
||||||
"µ",
|
|
||||||
"n",
|
|
||||||
"p",
|
|
||||||
"f",
|
|
||||||
"a",
|
|
||||||
"z",
|
|
||||||
"y",
|
|
||||||
};
|
|
||||||
|
|
||||||
public static String TestGetPrefix(Double v, String unit)
|
|
||||||
{
|
|
||||||
if (v == 0)
|
|
||||||
return "";
|
|
||||||
|
|
||||||
var log10 = Math.Log10(v / 10);
|
|
||||||
var l = (Int32)Math.Floor(log10 / 3);
|
|
||||||
var lookUp = l > 0 ? Big : Small;
|
|
||||||
var i = Math.Abs(l);
|
|
||||||
|
|
||||||
return $"{v / Math.Pow(10.0, l * 3.0)} {lookUp[i]}{unit}";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static String TestGetPrefix(Decimal v, String unit)
|
|
||||||
{
|
|
||||||
if (v == 0m)
|
|
||||||
return "";
|
|
||||||
|
|
||||||
var d = (Double)v;
|
|
||||||
var log10 = Math.Log10(d / 10);
|
|
||||||
var l = (Int32)Math.Floor(log10 / 3);
|
|
||||||
var lookUp = l > 0 ? Big : Small;
|
|
||||||
var i = Math.Abs(l);
|
|
||||||
|
|
||||||
return $"{d / Math.Pow(10.0, l * 3.0)} {lookUp[i]}{unit}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String TestGetPrefix2(Decimal v, String unit)
|
|
||||||
{
|
|
||||||
if (v == 0m)
|
|
||||||
return "";
|
|
||||||
|
|
||||||
var a = Math.Abs(v);
|
|
||||||
var s = Math.Sign(v);
|
|
||||||
|
|
||||||
var i = 0;
|
|
||||||
|
|
||||||
while (a >= 10000m)
|
|
||||||
{
|
|
||||||
a /= 1000;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
while (a < 10m)
|
|
||||||
{
|
|
||||||
a *= 1000;
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
|
|
||||||
var lookUp = i >= 0 ? Big : Small;
|
|
||||||
|
|
||||||
var r = Decimal.Floor(a * 10m) / 10m;
|
|
||||||
|
|
||||||
return $"{r*s} {lookUp[Math.Abs(i)]}{unit}";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,8 +5,8 @@ namespace InnovEnergy.Lib.WebServer;
|
||||||
|
|
||||||
public static class Default
|
public static class Default
|
||||||
{
|
{
|
||||||
public static IPEndPoint EndPoint { get; } = new IPEndPoint(0, 0);
|
public static IPEndPoint EndPoint { get; } = new IPEndPoint(0, 0);
|
||||||
public static Url Url { get; } = new Url("");
|
public static Url Url { get; } = new Url("");
|
||||||
public static HttpResponse HttpNotFound { get; } = new HttpResponse { StatusCode = 404 };
|
public static HttpResponse HttpNotFound { get; } = new HttpResponse { StatusCode = 404 };
|
||||||
public static HttpResponse HttpForbidden { get; } = new HttpResponse { StatusCode = 403 };
|
public static HttpResponse HttpForbidden { get; } = new HttpResponse { StatusCode = 403 };
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,6 @@
|
||||||
"react-plotly.js": "^2.6.0",
|
"react-plotly.js": "^2.6.0",
|
||||||
"react-router-dom": "^6.8.0",
|
"react-router-dom": "^6.8.0",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"react-window": "^1.8.9",
|
|
||||||
"reactflow": "^11.5.6",
|
"reactflow": "^11.5.6",
|
||||||
"rxjs": "^7.8.0",
|
"rxjs": "^7.8.0",
|
||||||
"sass": "^1.58.3",
|
"sass": "^1.58.3",
|
||||||
|
@ -17199,11 +17198,6 @@
|
||||||
"node": ">= 4.0.0"
|
"node": ">= 4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/memoize-one": {
|
|
||||||
"version": "5.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
|
|
||||||
"integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="
|
|
||||||
},
|
|
||||||
"node_modules/merge-descriptors": {
|
"node_modules/merge-descriptors": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||||
|
@ -20585,22 +20579,6 @@
|
||||||
"react-dom": ">=16.13"
|
"react-dom": ">=16.13"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-window": {
|
|
||||||
"version": "1.8.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.9.tgz",
|
|
||||||
"integrity": "sha512-+Eqx/fj1Aa5WnhRfj9dJg4VYATGwIUP2ItwItiJ6zboKWA6EX3lYDAXfGF2hyNqplEprhbtjbipiADEcwQ823Q==",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/runtime": "^7.0.0",
|
|
||||||
"memoize-one": ">=3.1.1 <6"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">8.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0",
|
|
||||||
"react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/reactflow": {
|
"node_modules/reactflow": {
|
||||||
"version": "11.5.6",
|
"version": "11.5.6",
|
||||||
"resolved": "https://registry.npmjs.org/reactflow/-/reactflow-11.5.6.tgz",
|
"resolved": "https://registry.npmjs.org/reactflow/-/reactflow-11.5.6.tgz",
|
||||||
|
@ -38023,11 +38001,6 @@
|
||||||
"fs-monkey": "^1.0.3"
|
"fs-monkey": "^1.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"memoize-one": {
|
|
||||||
"version": "5.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
|
|
||||||
"integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="
|
|
||||||
},
|
|
||||||
"merge-descriptors": {
|
"merge-descriptors": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||||
|
@ -40347,15 +40320,6 @@
|
||||||
"debounce": "^1.2.1"
|
"debounce": "^1.2.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-window": {
|
|
||||||
"version": "1.8.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.9.tgz",
|
|
||||||
"integrity": "sha512-+Eqx/fj1Aa5WnhRfj9dJg4VYATGwIUP2ItwItiJ6zboKWA6EX3lYDAXfGF2hyNqplEprhbtjbipiADEcwQ823Q==",
|
|
||||||
"requires": {
|
|
||||||
"@babel/runtime": "^7.0.0",
|
|
||||||
"memoize-one": ">=3.1.1 <6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"reactflow": {
|
"reactflow": {
|
||||||
"version": "11.5.6",
|
"version": "11.5.6",
|
||||||
"resolved": "https://registry.npmjs.org/reactflow/-/reactflow-11.5.6.tgz",
|
"resolved": "https://registry.npmjs.org/reactflow/-/reactflow-11.5.6.tgz",
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
"react-plotly.js": "^2.6.0",
|
"react-plotly.js": "^2.6.0",
|
||||||
"react-router-dom": "^6.8.0",
|
"react-router-dom": "^6.8.0",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"react-window": "^1.8.9",
|
|
||||||
"reactflow": "^11.5.6",
|
"reactflow": "^11.5.6",
|
||||||
"rxjs": "^7.8.0",
|
"rxjs": "^7.8.0",
|
||||||
"sass": "^1.58.3",
|
"sass": "^1.58.3",
|
||||||
|
|
|
@ -1,33 +1,48 @@
|
||||||
import { createContext, ReactNode, SetStateAction, useState } from "react";
|
import { createContext, ReactNode, useState } from "react";
|
||||||
import { TreeElement, ToggleElement } from "../Installations/Log/CheckboxTree";
|
import { TreeElement } from "../Installations/Log/CheckboxTree";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
interface LogContextProviderProps {
|
interface LogContextProviderProps {
|
||||||
toggles: TreeElement[] | null;
|
toggles: TreeElement[] | null;
|
||||||
setToggles: (value: TreeElement[]) => void;
|
setToggles: (value: TreeElement[]) => void;
|
||||||
checkedToggles: ToggleElement | null;
|
checkedToggles: string[];
|
||||||
setCheckedToggles: React.Dispatch<SetStateAction<ToggleElement | null>>;
|
setChecked: (newValue: string) => void;
|
||||||
|
removeChecked: (value: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LogContext = createContext<LogContextProviderProps>({
|
export const LogContext = createContext<LogContextProviderProps>({
|
||||||
toggles: [],
|
toggles: [],
|
||||||
setToggles: () => {},
|
setToggles: () => {},
|
||||||
checkedToggles: {},
|
checkedToggles: [],
|
||||||
setCheckedToggles: () => {},
|
setChecked: () => {},
|
||||||
|
removeChecked: () => {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const LogContextProvider = ({ children }: { children: ReactNode }) => {
|
const LogContextProvider = ({ children }: { children: ReactNode }) => {
|
||||||
const [toggles, setToggles] = useState<TreeElement[] | null>(null);
|
const [toggles, setToggles] = useState<TreeElement[] | null>(null);
|
||||||
const [checkedToggles, setCheckedToggles] = useState<ToggleElement | null>(
|
const [checkedToggles, setCheckedToggles] = useState<string[]>([]);
|
||||||
null
|
|
||||||
);
|
const setChecked = (newValue: string) => {
|
||||||
|
if (checkedToggles.length === 5) {
|
||||||
|
const removedChecked = checkedToggles.slice(1);
|
||||||
|
setCheckedToggles([...removedChecked, newValue]);
|
||||||
|
} else {
|
||||||
|
setCheckedToggles([...checkedToggles, newValue]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeChecked = (value: string) => {
|
||||||
|
setCheckedToggles(checkedToggles.filter((toggle) => toggle !== value));
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LogContext.Provider
|
<LogContext.Provider
|
||||||
value={{
|
value={{
|
||||||
toggles,
|
toggles,
|
||||||
setToggles,
|
setToggles,
|
||||||
checkedToggles,
|
checkedToggles,
|
||||||
setCheckedToggles,
|
setChecked,
|
||||||
|
removeChecked,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|
|
@ -21,7 +21,8 @@ export interface TreeElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
const CheckboxTree = () => {
|
const CheckboxTree = () => {
|
||||||
const { toggles, setCheckedToggles, checkedToggles } = useContext(LogContext);
|
const { toggles, setChecked, checkedToggles, removeChecked } =
|
||||||
|
useContext(LogContext);
|
||||||
const routeMatch = useRouteMatch([
|
const routeMatch = useRouteMatch([
|
||||||
routes.installations + routes.list + routes.log + ":id",
|
routes.installations + routes.list + routes.log + ":id",
|
||||||
]);
|
]);
|
||||||
|
@ -30,29 +31,17 @@ const CheckboxTree = () => {
|
||||||
return element.children.length > 0 ? renderTree(element.children) : null;
|
return element.children.length > 0 ? renderTree(element.children) : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCheckChildren = (children: TreeElement[], checked?: boolean) => {
|
|
||||||
if (children.length > 0) {
|
|
||||||
children.forEach((child) => {
|
|
||||||
setCheckedToggles((prevState) => {
|
|
||||||
return {
|
|
||||||
...prevState,
|
|
||||||
[child.id]: !checked,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
if (child.children.length > 0) {
|
|
||||||
handleCheckChildren(child.children, checked);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleClick = (
|
const handleClick = (
|
||||||
event: React.MouseEvent<HTMLButtonElement, MouseEvent>,
|
event: React.MouseEvent<HTMLButtonElement, MouseEvent>,
|
||||||
element: TreeElement,
|
element: TreeElement,
|
||||||
checked?: boolean
|
checked?: string
|
||||||
) => {
|
) => {
|
||||||
event.stopPropagation();
|
if (checked) {
|
||||||
handleCheckChildren([element], checked);
|
removeChecked(element.id);
|
||||||
|
} else {
|
||||||
|
event.stopPropagation();
|
||||||
|
setChecked(element.id);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleExpandClick = (
|
const handleExpandClick = (
|
||||||
|
@ -63,7 +52,7 @@ const CheckboxTree = () => {
|
||||||
|
|
||||||
const renderTree = (data: TreeElement[]): ReactNode => {
|
const renderTree = (data: TreeElement[]): ReactNode => {
|
||||||
return data.map((element) => {
|
return data.map((element) => {
|
||||||
const checked = checkedToggles?.[element.id];
|
const checked = checkedToggles.find((toggle) => element.id === toggle);
|
||||||
const splitName = element.name.split("/");
|
const splitName = element.name.split("/");
|
||||||
return (
|
return (
|
||||||
<TreeItem
|
<TreeItem
|
||||||
|
@ -73,10 +62,12 @@ const CheckboxTree = () => {
|
||||||
onClick={handleExpandClick}
|
onClick={handleExpandClick}
|
||||||
label={
|
label={
|
||||||
<>
|
<>
|
||||||
<Checkbox
|
{element.children.length === 0 && (
|
||||||
checked={checked}
|
<Checkbox
|
||||||
onClick={(e) => handleClick(e, element, checked)}
|
checked={!!checked}
|
||||||
/>
|
onClick={(e) => handleClick(e, element, checked)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{splitName[splitName.length - 1]}
|
{splitName[splitName.length - 1]}
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { DataRecord, RecordSeries } from "../../../dataCache/data";
|
||||||
import {
|
import {
|
||||||
GraphData,
|
GraphData,
|
||||||
createTimes,
|
createTimes,
|
||||||
flattenToggles,
|
|
||||||
getTreeElements,
|
getTreeElements,
|
||||||
isNumeric,
|
isNumeric,
|
||||||
parseCsv,
|
parseCsv,
|
||||||
|
@ -11,14 +10,13 @@ import {
|
||||||
transformToBarGraphData,
|
transformToBarGraphData,
|
||||||
} from "../../../util/graph.util";
|
} from "../../../util/graph.util";
|
||||||
import { TimeRange, TimeSpan, UnixTime } from "../../../dataCache/time";
|
import { TimeRange, TimeSpan, UnixTime } from "../../../dataCache/time";
|
||||||
import { memo, useContext, useEffect, useMemo, useState } from "react";
|
import { useCallback, useContext, useEffect, useMemo, useState } from "react";
|
||||||
import { BehaviorSubject, startWith, throttleTime, withLatestFrom } from "rxjs";
|
import { BehaviorSubject, startWith, throttleTime, withLatestFrom } from "rxjs";
|
||||||
import { S3Access } from "../../../dataCache/S3/S3Access";
|
import { S3Access } from "../../../dataCache/S3/S3Access";
|
||||||
import DataCache, { FetchResult } from "../../../dataCache/dataCache";
|
import DataCache, { FetchResult } from "../../../dataCache/dataCache";
|
||||||
import { LogContext } from "../../Context/LogContextProvider";
|
import { LogContext } from "../../Context/LogContextProvider";
|
||||||
import { isDefined } from "../../../dataCache/utils/maybe";
|
import { isDefined } from "../../../dataCache/utils/maybe";
|
||||||
import { Data, Layout } from "plotly.js";
|
import { Data, Layout, PlotRelayoutEvent } from "plotly.js";
|
||||||
import { VariableSizeList as List, areEqual } from "react-window";
|
|
||||||
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
|
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
import DateRangePicker from "./DateRangePicker";
|
import DateRangePicker from "./DateRangePicker";
|
||||||
|
@ -27,462 +25,6 @@ import { Alert } from "@mui/material";
|
||||||
|
|
||||||
const NUMBER_OF_NODES = 100;
|
const NUMBER_OF_NODES = 100;
|
||||||
|
|
||||||
export const testData = `/AcDc/SystemControl/Alarms;;
|
|
||||||
/AcDc/SystemControl/CommunicationTimeout;00:00:10;
|
|
||||||
/AcDc/SystemControl/SystemConfig;AcDcAndDcDc;
|
|
||||||
/AcDc/SystemControl/ResetAlarmsAndWarnings;False;
|
|
||||||
/AcDc/SystemControl/TargetSlave;0;
|
|
||||||
/AcDc/SystemControl/UseSlaveIdForAddressing;False;
|
|
||||||
/AcDc/SystemControl/ReferenceFrame;Producer;
|
|
||||||
/AcDc/SystemControl/SlaveErrorHandling;Relaxed;
|
|
||||||
/AcDc/SystemControl/SubSlaveErrorHandling;Strict;
|
|
||||||
/AcDc/SystemControl/PowerSetPointActivation;Immediate;
|
|
||||||
/AcDc/SystemControl/PowerSetPointTrigger;Wait;
|
|
||||||
/AcDc/SystemControl/DeviceState;Operation;
|
|
||||||
/AcDc/SystemControl/NumberOfConnectedSlaves;2;
|
|
||||||
/AcDc/SystemControl/NumberOfConnectedSubSlaves;0;
|
|
||||||
/AcDc/SystemControl/Warnings;;
|
|
||||||
/AcDc/Devices/1/Status/Ac/L1/Voltage;0;V
|
|
||||||
/AcDc/Devices/1/Status/Ac/L1/Current;0;A
|
|
||||||
/AcDc/Devices/1/Status/Ac/L1/Power/Apparent;0;VA
|
|
||||||
/AcDc/Devices/1/Status/Ac/L1/Power/Active;0;W
|
|
||||||
/AcDc/Devices/1/Status/Ac/L1/Power/Reactive;0;var
|
|
||||||
/AcDc/Devices/1/Status/Ac/L1/Power/Phi;0;rad
|
|
||||||
/AcDc/Devices/1/Status/Ac/L1/Power/CosPhi;1;
|
|
||||||
/AcDc/Devices/1/Status/Ac/L2/Voltage;0;V
|
|
||||||
/AcDc/Devices/1/Status/Ac/L2/Current;0;A
|
|
||||||
/AcDc/Devices/1/Status/Ac/L2/Power/Apparent;0;VA
|
|
||||||
/AcDc/Devices/1/Status/Ac/L2/Power/Active;0;W
|
|
||||||
/AcDc/Devices/1/Status/Ac/L2/Power/Reactive;0;var
|
|
||||||
/AcDc/Devices/1/Status/Ac/L2/Power/Phi;0;rad
|
|
||||||
/AcDc/Devices/1/Status/Ac/L2/Power/CosPhi;1;
|
|
||||||
/AcDc/Devices/1/Status/Ac/L3/Voltage;0;V
|
|
||||||
/AcDc/Devices/1/Status/Ac/L3/Current;0;A
|
|
||||||
/AcDc/Devices/1/Status/Ac/L3/Power/Apparent;0;VA
|
|
||||||
/AcDc/Devices/1/Status/Ac/L3/Power/Active;0;W
|
|
||||||
/AcDc/Devices/1/Status/Ac/L3/Power/Reactive;0;var
|
|
||||||
/AcDc/Devices/1/Status/Ac/L3/Power/Phi;0;rad
|
|
||||||
/AcDc/Devices/1/Status/Ac/L3/Power/CosPhi;1;
|
|
||||||
/AcDc/Devices/1/Status/Ac/Power/Apparent;0;VA
|
|
||||||
/AcDc/Devices/1/Status/Ac/Power/Active;0;W
|
|
||||||
/AcDc/Devices/1/Status/Ac/Power/Reactive;0;var
|
|
||||||
/AcDc/Devices/1/Status/Ac/Power/Phi;0;rad
|
|
||||||
/AcDc/Devices/1/Status/Ac/Power/CosPhi;1;
|
|
||||||
/AcDc/Devices/1/Status/Ac/Frequency;0;Hz
|
|
||||||
/AcDc/Devices/1/Status/Dc/Voltage;0;V
|
|
||||||
/AcDc/Devices/1/Status/Dc/Current;0;A
|
|
||||||
/AcDc/Devices/1/Status/Dc/Power;0;W
|
|
||||||
/AcDc/Devices/1/Status/PowerLimitedBy;Nothing;
|
|
||||||
/AcDc/Devices/1/Status/InverterState/Current;Idle;
|
|
||||||
/AcDc/Devices/1/Status/InverterState/OnLastAlarm;Idle;
|
|
||||||
/AcDc/Devices/1/Status/ActiveGridType;GridTied400V50Hz;
|
|
||||||
/AcDc/Devices/1/Status/Voltage/Intern/DcUpperHalf;0;V
|
|
||||||
/AcDc/Devices/1/Status/Voltage/Intern/DcLowerHalf;0;V
|
|
||||||
/AcDc/Devices/1/Status/Voltage/Intern/NToPe;0;V
|
|
||||||
/AcDc/Devices/1/Status/Voltage/Extern/DcUpperHalf;0;V
|
|
||||||
/AcDc/Devices/1/Status/Voltage/Extern/DcLowerHalf;0;V
|
|
||||||
/AcDc/Devices/1/Status/Voltage/Extern/NToPe;0;V
|
|
||||||
/AcDc/Devices/1/Status/Temperature/InletAir;0;°C
|
|
||||||
/AcDc/Devices/1/Status/Temperature/IgbtL1;0;°C
|
|
||||||
/AcDc/Devices/1/Status/Temperature/IgbtL2;0;°C
|
|
||||||
/AcDc/Devices/1/Status/Temperature/IgbtL3;0;°C
|
|
||||||
/AcDc/Devices/1/Status/Temperature/IgbtBalancer;0;°C
|
|
||||||
/AcDc/Devices/1/Status/OverloadCapacity/L1;0;%
|
|
||||||
/AcDc/Devices/1/Status/OverloadCapacity/L2;0;%
|
|
||||||
/AcDc/Devices/1/Status/OverloadCapacity/L3;0;%
|
|
||||||
/AcDc/Devices/1/Status/Nominal/AcFrequency;50;Hz
|
|
||||||
/AcDc/Devices/1/Status/Nominal/AcVoltage;400;V
|
|
||||||
/AcDc/Devices/1/Status/Nominal/Power;25000;W
|
|
||||||
/AcDc/Devices/1/Status/Alarms;;
|
|
||||||
/AcDc/Devices/1/Status/Warnings;;
|
|
||||||
/AcDc/Devices/1/Control/Ac/PhaseControl;Symmetric;
|
|
||||||
/AcDc/Devices/1/Control/Ac/GridType;GridTied400V50Hz;
|
|
||||||
/AcDc/Devices/1/Control/Ac/IslandMode/FrequencyOffset;0;Hz
|
|
||||||
/AcDc/Devices/1/Control/Ac/IslandMode/VoltageAdjustmentFactor;100;%
|
|
||||||
/AcDc/Devices/1/Control/Dc/ReferenceVoltage;750;V
|
|
||||||
/AcDc/Devices/1/Control/Dc/MinVoltage;730;V
|
|
||||||
/AcDc/Devices/1/Control/Dc/MaxVoltage;770;V
|
|
||||||
/AcDc/Devices/1/Control/Dc/PrechargeConfig;PrechargeDcWithSystemCtl;
|
|
||||||
/AcDc/Devices/1/Control/PowerStageEnable;True;
|
|
||||||
/AcDc/Devices/1/Control/ResetAlarmsAndWarnings;False;
|
|
||||||
/AcDc/Devices/2/Status/Ac/L1/Voltage;0;V
|
|
||||||
/AcDc/Devices/2/Status/Ac/L1/Current;0;A
|
|
||||||
/AcDc/Devices/2/Status/Ac/L1/Power/Apparent;0;VA
|
|
||||||
/AcDc/Devices/2/Status/Ac/L1/Power/Active;0;W
|
|
||||||
/AcDc/Devices/2/Status/Ac/L1/Power/Reactive;0;var
|
|
||||||
/AcDc/Devices/2/Status/Ac/L1/Power/Phi;0;rad
|
|
||||||
/AcDc/Devices/2/Status/Ac/L1/Power/CosPhi;1;
|
|
||||||
/AcDc/Devices/2/Status/Ac/L2/Voltage;0;V
|
|
||||||
/AcDc/Devices/2/Status/Ac/L2/Current;0;A
|
|
||||||
/AcDc/Devices/2/Status/Ac/L2/Power/Apparent;0;VA
|
|
||||||
/AcDc/Devices/2/Status/Ac/L2/Power/Active;0;W
|
|
||||||
/AcDc/Devices/2/Status/Ac/L2/Power/Reactive;0;var
|
|
||||||
/AcDc/Devices/2/Status/Ac/L2/Power/Phi;0;rad
|
|
||||||
/AcDc/Devices/2/Status/Ac/L2/Power/CosPhi;1;
|
|
||||||
/AcDc/Devices/2/Status/Ac/L3/Voltage;0;V
|
|
||||||
/AcDc/Devices/2/Status/Ac/L3/Current;0;A
|
|
||||||
/AcDc/Devices/2/Status/Ac/L3/Power/Apparent;0;VA
|
|
||||||
/AcDc/Devices/2/Status/Ac/L3/Power/Active;0;W
|
|
||||||
/AcDc/Devices/2/Status/Ac/L3/Power/Reactive;0;var
|
|
||||||
/AcDc/Devices/2/Status/Ac/L3/Power/Phi;0;rad
|
|
||||||
/AcDc/Devices/2/Status/Ac/L3/Power/CosPhi;1;
|
|
||||||
/AcDc/Devices/2/Status/Ac/Power/Apparent;0;VA
|
|
||||||
/AcDc/Devices/2/Status/Ac/Power/Active;0;W
|
|
||||||
/AcDc/Devices/2/Status/Ac/Power/Reactive;0;var
|
|
||||||
/AcDc/Devices/2/Status/Ac/Power/Phi;0;rad
|
|
||||||
/AcDc/Devices/2/Status/Ac/Power/CosPhi;1;
|
|
||||||
/AcDc/Devices/2/Status/Ac/Frequency;0;Hz
|
|
||||||
/AcDc/Devices/2/Status/Dc/Voltage;0;V
|
|
||||||
/AcDc/Devices/2/Status/Dc/Current;0;A
|
|
||||||
/AcDc/Devices/2/Status/Dc/Power;0;W
|
|
||||||
/AcDc/Devices/2/Status/PowerLimitedBy;Nothing;
|
|
||||||
/AcDc/Devices/2/Status/InverterState/Current;Idle;
|
|
||||||
/AcDc/Devices/2/Status/InverterState/OnLastAlarm;Idle;
|
|
||||||
/AcDc/Devices/2/Status/ActiveGridType;GridTied400V50Hz;
|
|
||||||
/AcDc/Devices/2/Status/Voltage/Intern/DcUpperHalf;0;V
|
|
||||||
/AcDc/Devices/2/Status/Voltage/Intern/DcLowerHalf;0;V
|
|
||||||
/AcDc/Devices/2/Status/Voltage/Intern/NToPe;0;V
|
|
||||||
/AcDc/Devices/2/Status/Voltage/Extern/DcUpperHalf;0;V
|
|
||||||
/AcDc/Devices/2/Status/Voltage/Extern/DcLowerHalf;0;V
|
|
||||||
/AcDc/Devices/2/Status/Voltage/Extern/NToPe;0;V
|
|
||||||
/AcDc/Devices/2/Status/Temperature/InletAir;0;°C
|
|
||||||
/AcDc/Devices/2/Status/Temperature/IgbtL1;0;°C
|
|
||||||
/AcDc/Devices/2/Status/Temperature/IgbtL2;0;°C
|
|
||||||
/AcDc/Devices/2/Status/Temperature/IgbtL3;0;°C
|
|
||||||
/AcDc/Devices/2/Status/Temperature/IgbtBalancer;0;°C
|
|
||||||
/AcDc/Devices/2/Status/OverloadCapacity/L1;0;%
|
|
||||||
/AcDc/Devices/2/Status/OverloadCapacity/L2;0;%
|
|
||||||
/AcDc/Devices/2/Status/OverloadCapacity/L3;0;%
|
|
||||||
/AcDc/Devices/2/Status/Nominal/AcFrequency;50;Hz
|
|
||||||
/AcDc/Devices/2/Status/Nominal/AcVoltage;400;V
|
|
||||||
/AcDc/Devices/2/Status/Nominal/Power;25000;W
|
|
||||||
/AcDc/Devices/2/Status/Alarms;;
|
|
||||||
/AcDc/Devices/2/Status/Warnings;;
|
|
||||||
/AcDc/Devices/2/Control/Ac/PhaseControl;Symmetric;
|
|
||||||
/AcDc/Devices/2/Control/Ac/GridType;GridTied400V50Hz;
|
|
||||||
/AcDc/Devices/2/Control/Ac/IslandMode/FrequencyOffset;0;Hz
|
|
||||||
/AcDc/Devices/2/Control/Ac/IslandMode/VoltageAdjustmentFactor;100;%
|
|
||||||
/AcDc/Devices/2/Control/Dc/ReferenceVoltage;750;V
|
|
||||||
/AcDc/Devices/2/Control/Dc/MinVoltage;730;V
|
|
||||||
/AcDc/Devices/2/Control/Dc/MaxVoltage;770;V
|
|
||||||
/AcDc/Devices/2/Control/Dc/PrechargeConfig;PrechargeDcWithSystemCtl;
|
|
||||||
/AcDc/Devices/2/Control/PowerStageEnable;True;
|
|
||||||
/AcDc/Devices/2/Control/ResetAlarmsAndWarnings;False;
|
|
||||||
/AcDc/Alarms;;
|
|
||||||
/AcDc/Warnings;;
|
|
||||||
/AcDc/Ac/L1/Voltage;0;V
|
|
||||||
/AcDc/Ac/L1/Current;0;A
|
|
||||||
/AcDc/Ac/L1/Power/Apparent;0;VA
|
|
||||||
/AcDc/Ac/L1/Power/Active;0;W
|
|
||||||
/AcDc/Ac/L1/Power/Reactive;0;var
|
|
||||||
/AcDc/Ac/L1/Power/Phi;0;rad
|
|
||||||
/AcDc/Ac/L1/Power/CosPhi;1;
|
|
||||||
/AcDc/Ac/L2/Voltage;0;V
|
|
||||||
/AcDc/Ac/L2/Current;0;A
|
|
||||||
/AcDc/Ac/L2/Power/Apparent;0;VA
|
|
||||||
/AcDc/Ac/L2/Power/Active;0;W
|
|
||||||
/AcDc/Ac/L2/Power/Reactive;0;var
|
|
||||||
/AcDc/Ac/L2/Power/Phi;0;rad
|
|
||||||
/AcDc/Ac/L2/Power/CosPhi;1;
|
|
||||||
/AcDc/Ac/L3/Voltage;0;V
|
|
||||||
/AcDc/Ac/L3/Current;0;A
|
|
||||||
/AcDc/Ac/L3/Power/Apparent;0;VA
|
|
||||||
/AcDc/Ac/L3/Power/Active;0;W
|
|
||||||
/AcDc/Ac/L3/Power/Reactive;0;var
|
|
||||||
/AcDc/Ac/L3/Power/Phi;0;rad
|
|
||||||
/AcDc/Ac/L3/Power/CosPhi;1;
|
|
||||||
/AcDc/Ac/Power/Apparent;0;VA
|
|
||||||
/AcDc/Ac/Power/Active;0;W
|
|
||||||
/AcDc/Ac/Power/Reactive;0;var
|
|
||||||
/AcDc/Ac/Power/Phi;0;rad
|
|
||||||
/AcDc/Ac/Power/CosPhi;1;
|
|
||||||
/AcDc/Ac/Frequency;0;Hz
|
|
||||||
/AcDc/Dc/Voltage;0;V
|
|
||||||
/AcDc/Dc/Current;0;A
|
|
||||||
/AcDc/Dc/Power;0;W
|
|
||||||
/DcDc/Dc/Link/Voltage;0;V
|
|
||||||
/DcDc/Dc/Link/Current;0;A
|
|
||||||
/DcDc/Dc/Link/Power;0;W
|
|
||||||
/DcDc/Dc/Battery/Voltage;0;V
|
|
||||||
/DcDc/Dc/Battery/Current;0;A
|
|
||||||
/DcDc/Dc/Battery/Power;0;W
|
|
||||||
/DcDc/SystemControl/Alarms;;
|
|
||||||
/DcDc/SystemControl/CommunicationTimeout;00:00:10;
|
|
||||||
/DcDc/SystemControl/SystemConfig;DcDcOnly;
|
|
||||||
/DcDc/SystemControl/ResetAlarmsAndWarnings;False;
|
|
||||||
/DcDc/SystemControl/TargetSlave;0;
|
|
||||||
/DcDc/SystemControl/UseSlaveIdForAddressing;False;
|
|
||||||
/DcDc/SystemControl/ReferenceFrame;Producer;
|
|
||||||
/DcDc/SystemControl/SlaveErrorHandling;Relaxed;
|
|
||||||
/DcDc/SystemControl/SubSlaveErrorHandling;Strict;
|
|
||||||
/DcDc/SystemControl/PowerSetPointActivation;Immediate;
|
|
||||||
/DcDc/SystemControl/PowerSetPointTrigger;Wait;
|
|
||||||
/DcDc/SystemControl/DeviceState;Operation;
|
|
||||||
/DcDc/SystemControl/NumberOfConnectedSlaves;2;
|
|
||||||
/DcDc/SystemControl/NumberOfConnectedSubSlaves;0;
|
|
||||||
/DcDc/SystemControl/Warnings;;
|
|
||||||
/DcDc/Devices/1/Status/Dc/Link/Voltage;0;V
|
|
||||||
/DcDc/Devices/1/Status/Dc/Link/Current;0;A
|
|
||||||
/DcDc/Devices/1/Status/Dc/Link/Power;0;W
|
|
||||||
/DcDc/Devices/1/Status/Dc/Battery/Voltage;0;V
|
|
||||||
/DcDc/Devices/1/Status/Dc/Battery/Current;0;A
|
|
||||||
/DcDc/Devices/1/Status/Dc/Battery/Power;0;W
|
|
||||||
/DcDc/Devices/1/Status/OverloadCapacity;0;%
|
|
||||||
/DcDc/Devices/1/Status/Temperature/InletAir;0;°C
|
|
||||||
/DcDc/Devices/1/Status/Temperature/HighVoltageModule;0;°C
|
|
||||||
/DcDc/Devices/1/Status/Temperature/LowVoltageModule;0;°C
|
|
||||||
/DcDc/Devices/1/Status/PowerLimitedBy;;
|
|
||||||
/DcDc/Devices/1/Status/Alarms;;
|
|
||||||
/DcDc/Devices/1/Status/Warnings;;
|
|
||||||
/DcDc/Devices/1/Control/Vcc/EndPointCurrent;50;A
|
|
||||||
/DcDc/Devices/1/Control/Vcc/EndPointVoltage;50;V
|
|
||||||
/DcDc/Devices/1/Control/Vcc/StartPointCurrent;5;A
|
|
||||||
/DcDc/Devices/1/Control/VoltageLimits/MinBatteryVoltageAlarm;0;V
|
|
||||||
/DcDc/Devices/1/Control/VoltageLimits/MaxBatteryVoltageAlarm;60;V
|
|
||||||
/DcDc/Devices/1/Control/VoltageLimits/MinBatteryVoltage;42;V
|
|
||||||
/DcDc/Devices/1/Control/VoltageLimits/MaxBatteryVoltage;57;V
|
|
||||||
/DcDc/Devices/1/Control/DroopControl/ReferenceVoltage;750;V
|
|
||||||
/DcDc/Devices/1/Control/DroopControl/LowerVoltage;55;V
|
|
||||||
/DcDc/Devices/1/Control/DroopControl/UpperVoltage;55;V
|
|
||||||
/DcDc/Devices/1/Control/DroopControl/VoltageDeadband;0;V
|
|
||||||
/DcDc/Devices/1/Control/CurrentControl/CurrentSetpoint;0;A
|
|
||||||
/DcDc/Devices/1/Control/CurrentControl/MaxCurrentChangePerMs;100;A
|
|
||||||
/DcDc/Devices/1/Control/MaxDcPower;5;W
|
|
||||||
/DcDc/Devices/1/Control/ControlMode;VoltageDroop;
|
|
||||||
/DcDc/Devices/1/Control/ResetAlarmsAndWarnings;False;
|
|
||||||
/DcDc/Devices/1/Control/PowerStageEnable;True;
|
|
||||||
/DcDc/Devices/2/Status/Dc/Link/Voltage;0;V
|
|
||||||
/DcDc/Devices/2/Status/Dc/Link/Current;0;A
|
|
||||||
/DcDc/Devices/2/Status/Dc/Link/Power;0;W
|
|
||||||
/DcDc/Devices/2/Status/Dc/Battery/Voltage;0;V
|
|
||||||
/DcDc/Devices/2/Status/Dc/Battery/Current;0;A
|
|
||||||
/DcDc/Devices/2/Status/Dc/Battery/Power;0;W
|
|
||||||
/DcDc/Devices/2/Status/OverloadCapacity;0;%
|
|
||||||
/DcDc/Devices/2/Status/Temperature/InletAir;0;°C
|
|
||||||
/DcDc/Devices/2/Status/Temperature/HighVoltageModule;0;°C
|
|
||||||
/DcDc/Devices/2/Status/Temperature/LowVoltageModule;0;°C
|
|
||||||
/DcDc/Devices/2/Status/PowerLimitedBy;;
|
|
||||||
/DcDc/Devices/2/Status/Alarms;;
|
|
||||||
/DcDc/Devices/2/Status/Warnings;;
|
|
||||||
/DcDc/Devices/2/Control/Vcc/EndPointCurrent;50;A
|
|
||||||
/DcDc/Devices/2/Control/Vcc/EndPointVoltage;50;V
|
|
||||||
/DcDc/Devices/2/Control/Vcc/StartPointCurrent;5;A
|
|
||||||
/DcDc/Devices/2/Control/VoltageLimits/MinBatteryVoltageAlarm;0;V
|
|
||||||
/DcDc/Devices/2/Control/VoltageLimits/MaxBatteryVoltageAlarm;60;V
|
|
||||||
/DcDc/Devices/2/Control/VoltageLimits/MinBatteryVoltage;42;V
|
|
||||||
/DcDc/Devices/2/Control/VoltageLimits/MaxBatteryVoltage;57;V
|
|
||||||
/DcDc/Devices/2/Control/DroopControl/ReferenceVoltage;750;V
|
|
||||||
/DcDc/Devices/2/Control/DroopControl/LowerVoltage;55;V
|
|
||||||
/DcDc/Devices/2/Control/DroopControl/UpperVoltage;55;V
|
|
||||||
/DcDc/Devices/2/Control/DroopControl/VoltageDeadband;0;V
|
|
||||||
/DcDc/Devices/2/Control/CurrentControl/CurrentSetpoint;0;A
|
|
||||||
/DcDc/Devices/2/Control/CurrentControl/MaxCurrentChangePerMs;100;A
|
|
||||||
/DcDc/Devices/2/Control/MaxDcPower;5;W
|
|
||||||
/DcDc/Devices/2/Control/ControlMode;VoltageDroop;
|
|
||||||
/DcDc/Devices/2/Control/ResetAlarmsAndWarnings;False;
|
|
||||||
/DcDc/Devices/2/Control/PowerStageEnable;True;
|
|
||||||
/DcDc/Alarms;;
|
|
||||||
/DcDc/Warnings;;
|
|
||||||
/Battery/Dc/Voltage;51.898;V
|
|
||||||
/Battery/Dc/Current;0.21000000000000002;A
|
|
||||||
/Battery/Dc/Power;10.898580000000003;W
|
|
||||||
/Battery/Eoc;True;
|
|
||||||
/Battery/Warnings;;
|
|
||||||
/Battery/Alarms;;
|
|
||||||
/Battery/Soc;99.9;%
|
|
||||||
/Battery/Devices/1/Dc/Voltage;51.69;V
|
|
||||||
/Battery/Devices/1/Dc/Current;0.05;A
|
|
||||||
/Battery/Devices/1/Dc/Power;2.5845000000000002;W
|
|
||||||
/Battery/Devices/1/Leds/Blue;Off;
|
|
||||||
/Battery/Devices/1/Leds/Red;Off;
|
|
||||||
/Battery/Devices/1/Leds/Green;On;
|
|
||||||
/Battery/Devices/1/Leds/Amber;Off;
|
|
||||||
/Battery/Devices/1/Temperatures/Heating;True;
|
|
||||||
/Battery/Devices/1/Temperatures/Board;46.5;°C
|
|
||||||
/Battery/Devices/1/Temperatures/Cells/Center;249.9;°C
|
|
||||||
/Battery/Devices/1/Temperatures/Cells/Left;249.5;°C
|
|
||||||
/Battery/Devices/1/Temperatures/Cells/Right;249.5;°C
|
|
||||||
/Battery/Devices/1/Temperatures/State;Operation;
|
|
||||||
/Battery/Devices/1/ConnectedToDcBus;True;
|
|
||||||
/Battery/Devices/1/Eoc;True;
|
|
||||||
/Battery/Devices/1/Warnings;;
|
|
||||||
/Battery/Devices/1/Alarms;;
|
|
||||||
/Battery/Devices/1/Soc;100;%
|
|
||||||
/Battery/Devices/1/MaxChargePower;5418.875;W
|
|
||||||
/Battery/Devices/1/MaxDischargePower;-4668.75;W
|
|
||||||
/Battery/Devices/2/Dc/Voltage;51.49;V
|
|
||||||
/Battery/Devices/2/Dc/Current;0.02;A
|
|
||||||
/Battery/Devices/2/Dc/Power;1.0298;W
|
|
||||||
/Battery/Devices/2/Leds/Blue;Off;
|
|
||||||
/Battery/Devices/2/Leds/Red;Off;
|
|
||||||
/Battery/Devices/2/Leds/Green;On;
|
|
||||||
/Battery/Devices/2/Leds/Amber;Off;
|
|
||||||
/Battery/Devices/2/Temperatures/Heating;True;
|
|
||||||
/Battery/Devices/2/Temperatures/Board;55;°C
|
|
||||||
/Battery/Devices/2/Temperatures/Cells/Center;251.4;°C
|
|
||||||
/Battery/Devices/2/Temperatures/Cells/Left;249.8;°C
|
|
||||||
/Battery/Devices/2/Temperatures/Cells/Right;254.2;°C
|
|
||||||
/Battery/Devices/2/Temperatures/State;Operation;
|
|
||||||
/Battery/Devices/2/ConnectedToDcBus;True;
|
|
||||||
/Battery/Devices/2/Eoc;True;
|
|
||||||
/Battery/Devices/2/Warnings;;
|
|
||||||
/Battery/Devices/2/Alarms;;
|
|
||||||
/Battery/Devices/2/Soc;100;%
|
|
||||||
/Battery/Devices/2/MaxChargePower;5398.95;W
|
|
||||||
/Battery/Devices/2/MaxDischargePower;-4648.900000000001;W
|
|
||||||
/Battery/Devices/3/Dc/Voltage;52.2;V
|
|
||||||
/Battery/Devices/3/Dc/Current;0.02;A
|
|
||||||
/Battery/Devices/3/Dc/Power;1.044;W
|
|
||||||
/Battery/Devices/3/Leds/Blue;Off;
|
|
||||||
/Battery/Devices/3/Leds/Red;Off;
|
|
||||||
/Battery/Devices/3/Leds/Green;On;
|
|
||||||
/Battery/Devices/3/Leds/Amber;Off;
|
|
||||||
/Battery/Devices/3/Temperatures/Heating;True;
|
|
||||||
/Battery/Devices/3/Temperatures/Board;47.5;°C
|
|
||||||
/Battery/Devices/3/Temperatures/Cells/Center;250.5;°C
|
|
||||||
/Battery/Devices/3/Temperatures/Cells/Left;249.8;°C
|
|
||||||
/Battery/Devices/3/Temperatures/Cells/Right;251.4;°C
|
|
||||||
/Battery/Devices/3/Temperatures/State;Operation;
|
|
||||||
/Battery/Devices/3/ConnectedToDcBus;True;
|
|
||||||
/Battery/Devices/3/Eoc;True;
|
|
||||||
/Battery/Devices/3/Warnings;;
|
|
||||||
/Battery/Devices/3/Alarms;;
|
|
||||||
/Battery/Devices/3/Soc;100;%
|
|
||||||
/Battery/Devices/3/MaxChargePower;5469.95;W
|
|
||||||
/Battery/Devices/3/MaxDischargePower;-4719.900000000001;W
|
|
||||||
/Battery/Devices/4/Dc/Voltage;51.94;V
|
|
||||||
/Battery/Devices/4/Dc/Current;0.03;A
|
|
||||||
/Battery/Devices/4/Dc/Power;1.5581999999999998;W
|
|
||||||
/Battery/Devices/4/Leds/Blue;Off;
|
|
||||||
/Battery/Devices/4/Leds/Red;Off;
|
|
||||||
/Battery/Devices/4/Leds/Green;On;
|
|
||||||
/Battery/Devices/4/Leds/Amber;Off;
|
|
||||||
/Battery/Devices/4/Temperatures/Heating;True;
|
|
||||||
/Battery/Devices/4/Temperatures/Board;47;°C
|
|
||||||
/Battery/Devices/4/Temperatures/Cells/Center;250;°C
|
|
||||||
/Battery/Devices/4/Temperatures/Cells/Left;249.8;°C
|
|
||||||
/Battery/Devices/4/Temperatures/Cells/Right;252.1;°C
|
|
||||||
/Battery/Devices/4/Temperatures/State;Operation;
|
|
||||||
/Battery/Devices/4/ConnectedToDcBus;False;
|
|
||||||
/Battery/Devices/4/Eoc;True;
|
|
||||||
/Battery/Devices/4/Warnings;;
|
|
||||||
/Battery/Devices/4/Alarms;;
|
|
||||||
/Battery/Devices/4/Soc;99.9;%
|
|
||||||
/Battery/Devices/4/MaxChargePower;5443.925;W
|
|
||||||
/Battery/Devices/4/MaxDischargePower;-4693.849999999999;W
|
|
||||||
/Battery/Devices/5/Dc/Voltage;52.17;V
|
|
||||||
/Battery/Devices/5/Dc/Current;0.09;A
|
|
||||||
/Battery/Devices/5/Dc/Power;4.6953;W
|
|
||||||
/Battery/Devices/5/Leds/Blue;Off;
|
|
||||||
/Battery/Devices/5/Leds/Red;Off;
|
|
||||||
/Battery/Devices/5/Leds/Green;On;
|
|
||||||
/Battery/Devices/5/Leds/Amber;Off;
|
|
||||||
/Battery/Devices/5/Temperatures/Heating;True;
|
|
||||||
/Battery/Devices/5/Temperatures/Board;48.5;°C
|
|
||||||
/Battery/Devices/5/Temperatures/Cells/Center;250.6;°C
|
|
||||||
/Battery/Devices/5/Temperatures/Cells/Left;249.8;°C
|
|
||||||
/Battery/Devices/5/Temperatures/Cells/Right;250.8;°C
|
|
||||||
/Battery/Devices/5/Temperatures/State;Operation;
|
|
||||||
/Battery/Devices/5/ConnectedToDcBus;True;
|
|
||||||
/Battery/Devices/5/Eoc;True;
|
|
||||||
/Battery/Devices/5/Warnings;;
|
|
||||||
/Battery/Devices/5/Alarms;;
|
|
||||||
/Battery/Devices/5/Soc;100;%
|
|
||||||
/Battery/Devices/5/MaxChargePower;5466.775;W
|
|
||||||
/Battery/Devices/5/MaxDischargePower;-4716.55;W
|
|
||||||
/GridMeter/Ac/L1/Voltage;243;V
|
|
||||||
/GridMeter/Ac/L1/Current;-12.360750198364258;A
|
|
||||||
/GridMeter/Ac/L1/Power/Apparent;3009.25;VA
|
|
||||||
/GridMeter/Ac/L1/Power/Active;-2969;W
|
|
||||||
/GridMeter/Ac/L1/Power/Reactive;502;var
|
|
||||||
/GridMeter/Ac/L1/Power/Phi;2.974096306323614;rad
|
|
||||||
/GridMeter/Ac/L1/Power/CosPhi;-0.9860052513602484;
|
|
||||||
/GridMeter/Ac/L2/Voltage;243.60000610351562;V
|
|
||||||
/GridMeter/Ac/L2/Current;-12.548500061035156;A
|
|
||||||
/GridMeter/Ac/L2/Power/Apparent;3043;VA
|
|
||||||
/GridMeter/Ac/L2/Power/Active;-3033;W
|
|
||||||
/GridMeter/Ac/L2/Power/Reactive;351;var
|
|
||||||
/GridMeter/Ac/L2/Power/Phi;3.026378172298827;rad
|
|
||||||
/GridMeter/Ac/L2/Power/CosPhi;-0.9933701504473591;
|
|
||||||
/GridMeter/Ac/L3/Voltage;244.39999389648438;V
|
|
||||||
/GridMeter/Ac/L3/Current;-13.57349967956543;A
|
|
||||||
/GridMeter/Ac/L3/Power/Apparent;3317;VA
|
|
||||||
/GridMeter/Ac/L3/Power/Active;-3313;W
|
|
||||||
/GridMeter/Ac/L3/Power/Reactive;-73.25;var
|
|
||||||
/GridMeter/Ac/L3/Power/Phi;-3.1194863851016974;rad
|
|
||||||
/GridMeter/Ac/L3/Power/CosPhi;-0.9997556663972327;
|
|
||||||
/GridMeter/Ac/Power/Apparent;9347.579101697936;VA
|
|
||||||
/GridMeter/Ac/Power/Active;-9315;W
|
|
||||||
/GridMeter/Ac/Power/Reactive;779.75;var
|
|
||||||
/GridMeter/Ac/Power/Phi;3.058078286561564;rad
|
|
||||||
/GridMeter/Ac/Power/CosPhi;-0.9965147016844159;
|
|
||||||
/GridMeter/Ac/Frequency;50;Hz
|
|
||||||
/CriticalLoad/Ac/L1/Voltage;244;V
|
|
||||||
/CriticalLoad/Ac/L1/Current;0;A
|
|
||||||
/CriticalLoad/Ac/L1/Power/Apparent;0;VA
|
|
||||||
/CriticalLoad/Ac/L1/Power/Active;0;W
|
|
||||||
/CriticalLoad/Ac/L1/Power/Reactive;0;var
|
|
||||||
/CriticalLoad/Ac/L1/Power/Phi;0;rad
|
|
||||||
/CriticalLoad/Ac/L1/Power/CosPhi;1;
|
|
||||||
/CriticalLoad/Ac/L2/Voltage;243;V
|
|
||||||
/CriticalLoad/Ac/L2/Current;0;A
|
|
||||||
/CriticalLoad/Ac/L2/Power/Apparent;0;VA
|
|
||||||
/CriticalLoad/Ac/L2/Power/Active;0;W
|
|
||||||
/CriticalLoad/Ac/L2/Power/Reactive;0;var
|
|
||||||
/CriticalLoad/Ac/L2/Power/Phi;0;rad
|
|
||||||
/CriticalLoad/Ac/L2/Power/CosPhi;1;
|
|
||||||
/CriticalLoad/Ac/L3/Voltage;245.6999969482422;V
|
|
||||||
/CriticalLoad/Ac/L3/Current;0;A
|
|
||||||
/CriticalLoad/Ac/L3/Power/Apparent;0;VA
|
|
||||||
/CriticalLoad/Ac/L3/Power/Active;0;W
|
|
||||||
/CriticalLoad/Ac/L3/Power/Reactive;0;var
|
|
||||||
/CriticalLoad/Ac/L3/Power/Phi;0;rad
|
|
||||||
/CriticalLoad/Ac/L3/Power/CosPhi;1;
|
|
||||||
/CriticalLoad/Ac/Power/Apparent;0;VA
|
|
||||||
/CriticalLoad/Ac/Power/Active;0;W
|
|
||||||
/CriticalLoad/Ac/Power/Reactive;0;var
|
|
||||||
/CriticalLoad/Ac/Power/Phi;0;rad
|
|
||||||
/CriticalLoad/Ac/Power/CosPhi;1;
|
|
||||||
/CriticalLoad/Ac/Frequency;50;Hz
|
|
||||||
/Relays/K1AcInIsConnectedToGrid;True;
|
|
||||||
/Relays/K2AcInIsConnectedToAcOut;True;
|
|
||||||
/Relays/K3Inverter1IsConnectedToAcOut;True;
|
|
||||||
/Relays/K3Inverter2IsConnectedToAcOut;True;
|
|
||||||
/Relays/K3Inverter3IsConnectedToAcOut;True;
|
|
||||||
/Relays/K3Inverter4IsConnectedToAcOut;True;
|
|
||||||
/Relays/FiWarning;False;
|
|
||||||
/Relays/FiError;False;
|
|
||||||
/Relays/K2ConnectAcInToAcOut;True;
|
|
||||||
/Relays/K3InvertersAreConnectedToAcOut;True;
|
|
||||||
/Mppt/Dc/Voltage;772.454;V
|
|
||||||
/Mppt/Dc/Current;10.655000000000001;A
|
|
||||||
/Mppt/Dc/Power;8230.497370000001;W
|
|
||||||
/Mppt/Strings/1/Voltage;690.09;V
|
|
||||||
/Mppt/Strings/1/Current;3.221;A
|
|
||||||
/Mppt/Strings/1/Power;2222.7798900000003;W
|
|
||||||
/Mppt/Strings/2/Voltage;599.549;V
|
|
||||||
/Mppt/Strings/2/Current;3.23;A
|
|
||||||
/Mppt/Strings/2/Power;1936.54327;W
|
|
||||||
/Mppt/Strings/3/Voltage;695.46;V
|
|
||||||
/Mppt/Strings/3/Current;3.371;A
|
|
||||||
/Mppt/Strings/3/Power;2344.39566;W
|
|
||||||
/Mppt/Strings/4/Voltage;623.849;V
|
|
||||||
/Mppt/Strings/4/Current;2.868;A
|
|
||||||
/Mppt/Strings/4/Power;1789.198932;W
|
|
||||||
/Config/MinSoc;20;
|
|
||||||
/Config/LastEoc;0;
|
|
||||||
/Config/PConstant;0.5;
|
|
||||||
/Config/ForceChargePower;1000000;
|
|
||||||
/Config/ForceDischargePower;-1000000;
|
|
||||||
/Config/MaxInverterPower;32000;
|
|
||||||
/Config/GridSetPoint;0;
|
|
||||||
/Config/SelfDischargePower;200;
|
|
||||||
/Config/HoldSocZone;1;
|
|
||||||
/Config/ControllerPConstant;0.5;
|
|
||||||
/SystemState/Message;Panic: Unknown State!;
|
|
||||||
/SystemState/Id;100;
|
|
||||||
/LoadOnDc/Power;100;`;
|
|
||||||
|
|
||||||
const s3Access = new S3Access(
|
const s3Access = new S3Access(
|
||||||
"saliomameiringen",
|
"saliomameiringen",
|
||||||
"sos-ch-dk-2",
|
"sos-ch-dk-2",
|
||||||
|
@ -525,11 +67,9 @@ const ScalarGraph = () => {
|
||||||
timeRange[0].toDate(),
|
timeRange[0].toDate(),
|
||||||
timeRange[timeRange.length - 1].toDate(),
|
timeRange[timeRange.length - 1].toDate(),
|
||||||
]);
|
]);
|
||||||
const [uiRevision, setUiRevision] = useState(Math.random());
|
|
||||||
const [plotTitles, setPlotTitles] = useState<string[]>([]);
|
const [plotTitles, setPlotTitles] = useState<string[]>([]);
|
||||||
|
|
||||||
const { toggles, setToggles, setCheckedToggles, checkedToggles } =
|
const { toggles, setToggles, checkedToggles } = useContext(LogContext);
|
||||||
useContext(LogContext);
|
|
||||||
|
|
||||||
const times$ = useMemo(() => new BehaviorSubject(timeRange), []);
|
const times$ = useMemo(() => new BehaviorSubject(timeRange), []);
|
||||||
|
|
||||||
|
@ -548,7 +88,6 @@ const ScalarGraph = () => {
|
||||||
if (toggles === null && toggleValues && toggleValues.value) {
|
if (toggles === null && toggleValues && toggleValues.value) {
|
||||||
const treeElements = getTreeElements(toggleValues.value);
|
const treeElements = getTreeElements(toggleValues.value);
|
||||||
setToggles(treeElements);
|
setToggles(treeElements);
|
||||||
setCheckedToggles(flattenToggles(treeElements));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return () => subscription.unsubscribe();
|
return () => subscription.unsubscribe();
|
||||||
|
@ -597,143 +136,118 @@ const ScalarGraph = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getCacheSeries = (xaxisRange0: Date, xaxisRange1: Date) => {
|
const getCacheSeries = useCallback(
|
||||||
const times = createTimes(
|
(xaxisRange0: Date, xaxisRange1: Date) => {
|
||||||
TimeRange.fromTimes(
|
const times = createTimes(
|
||||||
UnixTime.fromDate(xaxisRange0),
|
TimeRange.fromTimes(
|
||||||
UnixTime.fromDate(xaxisRange1)
|
UnixTime.fromDate(xaxisRange0),
|
||||||
),
|
UnixTime.fromDate(xaxisRange1)
|
||||||
NUMBER_OF_NODES
|
),
|
||||||
|
NUMBER_OF_NODES
|
||||||
|
);
|
||||||
|
cache.getSeries(times);
|
||||||
|
times$.next(times);
|
||||||
|
},
|
||||||
|
[cache, times$]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleRelayout = useCallback(
|
||||||
|
(params: PlotRelayoutEvent) => {
|
||||||
|
const xaxisRange0 = params["xaxis.range[0]"];
|
||||||
|
const xaxisRange1 = params["xaxis.range[1]"];
|
||||||
|
if (xaxisRange0 && xaxisRange1) {
|
||||||
|
const range0 = new Date(xaxisRange0);
|
||||||
|
const range1 = new Date(xaxisRange1);
|
||||||
|
setRange([range0, range1]);
|
||||||
|
getCacheSeries(range0, range1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[getCacheSeries]
|
||||||
|
);
|
||||||
|
|
||||||
|
const renderGraphs = () => {
|
||||||
|
if (checkedToggles.length > 0) {
|
||||||
|
const coordinateTimeSeries = transformToGraphData(timeSeries);
|
||||||
|
const visibleGraphs = Object.keys(coordinateTimeSeries).filter((path) => {
|
||||||
|
console.log('checkedToggles',coordinateTimeSeries, checkedToggles)
|
||||||
|
return checkedToggles.find((toggle) => toggle === path)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
console.log('visibleGraphs', visibleGraphs)
|
||||||
|
if (visibleGraphs.length > 0) {
|
||||||
|
return (
|
||||||
|
<div style={{ marginTop: "20px" }}>
|
||||||
|
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
||||||
|
<DateRangePicker
|
||||||
|
setRange={setRange}
|
||||||
|
range={range}
|
||||||
|
getCacheSeries={getCacheSeries}
|
||||||
|
/>
|
||||||
|
</LocalizationProvider>
|
||||||
|
{visibleGraphs.map((path) => {
|
||||||
|
const isScalar = isNumeric(coordinateTimeSeries[path].y[0]);
|
||||||
|
const data = isScalar
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
...coordinateTimeSeries[path],
|
||||||
|
type: "scatter",
|
||||||
|
mode: "lines",
|
||||||
|
fill: "tozeroy",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: transformToBarGraphData(coordinateTimeSeries[path]);
|
||||||
|
const barGraphLayout: Partial<Layout> = !isScalar
|
||||||
|
? {
|
||||||
|
bargap: 0,
|
||||||
|
barmode: "stack",
|
||||||
|
barnorm: "percent",
|
||||||
|
}
|
||||||
|
: {};
|
||||||
|
console.log("graphdata", coordinateTimeSeries);
|
||||||
|
return (
|
||||||
|
<Plot
|
||||||
|
key={path}
|
||||||
|
data={data as Data[]}
|
||||||
|
layout={{
|
||||||
|
width: 1000,
|
||||||
|
height: 500,
|
||||||
|
title: path,
|
||||||
|
xaxis: {
|
||||||
|
autorange: false,
|
||||||
|
range: range,
|
||||||
|
type: "date",
|
||||||
|
},
|
||||||
|
yaxis: {
|
||||||
|
rangemode: "tozero",
|
||||||
|
},
|
||||||
|
...barGraphLayout,
|
||||||
|
}}
|
||||||
|
config={{
|
||||||
|
modeBarButtonsToRemove: [
|
||||||
|
"lasso2d",
|
||||||
|
"select2d",
|
||||||
|
"pan2d",
|
||||||
|
"autoScale2d",
|
||||||
|
],
|
||||||
|
}}
|
||||||
|
onRelayout={handleRelayout}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Alert sx={{ mt: 2 }} severity="info">
|
||||||
|
<FormattedMessage
|
||||||
|
id="makeASelection"
|
||||||
|
defaultMessage="Please make a selection on the left"
|
||||||
|
/>
|
||||||
|
</Alert>
|
||||||
);
|
);
|
||||||
cache.getSeries(times);
|
|
||||||
times$.next(times);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const Row = memo((props: any) => {
|
return <>{renderGraphs()}</>;
|
||||||
const { data, index, style } = props;
|
|
||||||
const visibleGraphs = Object.keys(data).filter((path) => {
|
|
||||||
return checkedToggles ? checkedToggles[path] : false;
|
|
||||||
});
|
|
||||||
if (data[visibleGraphs[index]]) {
|
|
||||||
const isScalar = isNumeric(data[visibleGraphs[index]].y[0]);
|
|
||||||
const graphData = isScalar
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
...data[visibleGraphs[index]],
|
|
||||||
type: "scatter",
|
|
||||||
mode: "lines+markers",
|
|
||||||
fill: "tozeroy",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: transformToBarGraphData(data[visibleGraphs[index]]);
|
|
||||||
const barGraphLayout: Partial<Layout> = !isScalar
|
|
||||||
? {
|
|
||||||
bargap: 0,
|
|
||||||
barmode: "stack",
|
|
||||||
barnorm: "percent",
|
|
||||||
}
|
|
||||||
: {};
|
|
||||||
return (
|
|
||||||
<div style={style}>
|
|
||||||
<Plot
|
|
||||||
key={index}
|
|
||||||
data={graphData as Data[]}
|
|
||||||
layout={{
|
|
||||||
width: 1000,
|
|
||||||
height: 500,
|
|
||||||
autosize: true,
|
|
||||||
title: visibleGraphs[index],
|
|
||||||
uirevision: uiRevision,
|
|
||||||
xaxis: {
|
|
||||||
autorange: false,
|
|
||||||
range: range,
|
|
||||||
type: "date",
|
|
||||||
},
|
|
||||||
yaxis: {
|
|
||||||
rangemode: "tozero",
|
|
||||||
},
|
|
||||||
...barGraphLayout,
|
|
||||||
}}
|
|
||||||
config={{
|
|
||||||
modeBarButtonsToRemove: [
|
|
||||||
"lasso2d",
|
|
||||||
"select2d",
|
|
||||||
"pan2d",
|
|
||||||
"autoScale2d",
|
|
||||||
],
|
|
||||||
}}
|
|
||||||
onUpdate={(params) => {
|
|
||||||
console.log("event onupdate", params);
|
|
||||||
}}
|
|
||||||
onSliderChange={(params) => {
|
|
||||||
console.log("event sliderchange", params);
|
|
||||||
}}
|
|
||||||
onRestyle={(params) => {
|
|
||||||
console.log("event restyle", params);
|
|
||||||
}}
|
|
||||||
onRelayout={(params) => {
|
|
||||||
console.log("event relayout", params);
|
|
||||||
|
|
||||||
const xaxisRange0 = params["xaxis.range[0]"];
|
|
||||||
const xaxisRange1 = params["xaxis.range[1]"];
|
|
||||||
console.log("relayout", xaxisRange0, xaxisRange1);
|
|
||||||
if (xaxisRange0 && xaxisRange1) {
|
|
||||||
console.log("relayout", xaxisRange0, xaxisRange1);
|
|
||||||
const range0 = new Date(xaxisRange0);
|
|
||||||
const range1 = new Date(xaxisRange1);
|
|
||||||
|
|
||||||
setRange([range0, range1]);
|
|
||||||
setUiRevision(Math.random());
|
|
||||||
getCacheSeries(range0, range1);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}, areEqual);
|
|
||||||
|
|
||||||
if (
|
|
||||||
checkedToggles &&
|
|
||||||
Object.keys(checkedToggles).find((toggle) => {
|
|
||||||
return checkedToggles[toggle];
|
|
||||||
})
|
|
||||||
) {
|
|
||||||
const coordinateTimeSeries = transformToGraphData(timeSeries);
|
|
||||||
return (
|
|
||||||
<div style={{ marginTop: "20px" }}>
|
|
||||||
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
|
||||||
<DateRangePicker
|
|
||||||
setRange={setRange}
|
|
||||||
range={range}
|
|
||||||
getCacheSeries={getCacheSeries}
|
|
||||||
/>
|
|
||||||
</LocalizationProvider>
|
|
||||||
<List
|
|
||||||
height={1000}
|
|
||||||
itemCount={
|
|
||||||
Object.keys(checkedToggles).filter(
|
|
||||||
(toggle) => checkedToggles[toggle]
|
|
||||||
).length - 1
|
|
||||||
}
|
|
||||||
itemSize={() => 500}
|
|
||||||
width="100%"
|
|
||||||
itemData={coordinateTimeSeries}
|
|
||||||
>
|
|
||||||
{Row}
|
|
||||||
</List>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Alert sx={{ mt: 2 }} severity="info">
|
|
||||||
<FormattedMessage
|
|
||||||
id="makeASelection"
|
|
||||||
defaultMessage="Please make a selection on the left"
|
|
||||||
/>
|
|
||||||
</Alert>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
export default ScalarGraph;
|
export default ScalarGraph;
|
||||||
|
|
|
@ -1,79 +1,79 @@
|
||||||
import { Box } from "@mui/material";
|
import {Box} from "@mui/material";
|
||||||
import { getBoxColor } from "../../../util/graph.util";
|
import {getBoxColor} from "../../../util/graph.util";
|
||||||
|
|
||||||
export type BoxData = {
|
export type BoxData = {
|
||||||
label: string;
|
label: string;
|
||||||
values: (string | number)[];
|
values: (string | number)[];
|
||||||
unit: string;
|
unit: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TopologyBoxProps = {
|
export type TopologyBoxProps = {
|
||||||
title?: string;
|
title?: string;
|
||||||
data?: BoxData;
|
data?: BoxData;
|
||||||
};
|
};
|
||||||
|
|
||||||
const isInt = (value: number) => {
|
const isInt = (value: number) => {
|
||||||
return value % 1 === 0;
|
return value % 1 === 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const BOX_SIZE = 85;
|
export const BOX_SIZE = 85;
|
||||||
const TopologyBox = (props: TopologyBoxProps) => {
|
const TopologyBox = (props: TopologyBoxProps) => {
|
||||||
const { titleColor, boxColor } = getBoxColor(props.title);
|
const {titleColor, boxColor} = getBoxColor(props.title);
|
||||||
if (props.title === "Battery") console.log(props.data?.values, "data");
|
return (
|
||||||
return (
|
<Box
|
||||||
<Box
|
sx={{
|
||||||
sx={{
|
visibility: props.title ? "visible" : "hidden",
|
||||||
visibility: props.title ? "visible" : "hidden",
|
height: BOX_SIZE + "px",
|
||||||
height: BOX_SIZE + "px",
|
width: BOX_SIZE + "px",
|
||||||
width: BOX_SIZE + "px",
|
borderRadius: "4px",
|
||||||
borderRadius: "4px",
|
color: "white",
|
||||||
color: "white",
|
}}
|
||||||
}}
|
>
|
||||||
>
|
<p
|
||||||
<p
|
style={{
|
||||||
style={{
|
marginBlockStart: "0",
|
||||||
marginBlockStart: "0",
|
marginBlockEnd: "0",
|
||||||
marginBlockEnd: "0",
|
backgroundColor: titleColor,
|
||||||
backgroundColor: titleColor,
|
padding: "5px",
|
||||||
padding: "5px",
|
borderTopLeftRadius: "4px",
|
||||||
borderTopLeftRadius: "4px",
|
borderTopRightRadius: "4px",
|
||||||
borderTopRightRadius: "4px",
|
display: "flex",
|
||||||
display: "flex",
|
justifyContent: "center",
|
||||||
justifyContent: "center",
|
}}
|
||||||
}}
|
>
|
||||||
>
|
{props.title}
|
||||||
{props.title}
|
</p>
|
||||||
</p>
|
<div
|
||||||
<div
|
style={{
|
||||||
style={{
|
backgroundColor: boxColor,
|
||||||
backgroundColor: boxColor,
|
borderBottomLeftRadius: "4px",
|
||||||
borderBottomLeftRadius: "4px",
|
borderBottomRightRadius: "4px",
|
||||||
borderBottomRightRadius: "4px",
|
padding: "5px",
|
||||||
padding: "5px",
|
height: "51px",
|
||||||
height: "51px",
|
}}
|
||||||
}}
|
>
|
||||||
>
|
{props.data && (
|
||||||
{props.data && (
|
<>
|
||||||
<>
|
{props.data.values.map((value, index) => {
|
||||||
{props.data.values.map((value, index) => {
|
return (
|
||||||
return (
|
<p
|
||||||
<p
|
key={props.title + '-' + index}
|
||||||
style={{ marginBlockStart: "0", marginBlockEnd: "2px" }}
|
style={{marginBlockStart: "0", marginBlockEnd: "2px"}}
|
||||||
// eslint-disable-next-line formatjs/no-literal-string-in-jsx
|
// eslint-disable-next-line formatjs/no-literal-string-in-jsx
|
||||||
>{`${
|
>{`${
|
||||||
props.data && props.data.values.length === 3
|
props.data && props.data.values.length === 3
|
||||||
? "L" + (index + 1) + " "
|
? "L" + (index + 1) + " "
|
||||||
: ""
|
: ""
|
||||||
}${
|
}${
|
||||||
!isInt(Number(value)) ? Number(value).toPrecision(4) : value
|
!isInt(Number(value)) ? Number(value).toPrecision(4) : value
|
||||||
}${props.data?.unit}`}</p>
|
}${props.data?.unit}`}</p>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default TopologyBox;
|
export default TopologyBox;
|
||||||
|
|
|
@ -9,7 +9,6 @@ export type TopologyFlowProps = {
|
||||||
hidden?: boolean;
|
hidden?: boolean;
|
||||||
};
|
};
|
||||||
const TopologyFlow = (props: TopologyFlowProps) => {
|
const TopologyFlow = (props: TopologyFlowProps) => {
|
||||||
console.log("amount", props.amount, props.data?.values);
|
|
||||||
const length = Math.abs((props.amount ?? 1) * BOX_SIZE);
|
const length = Math.abs((props.amount ?? 1) * BOX_SIZE);
|
||||||
const values = props.data?.values;
|
const values = props.data?.values;
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { Datum, TypedArray } from "plotly.js";
|
import { Datum, TypedArray } from "plotly.js";
|
||||||
import {
|
import {
|
||||||
TreeElement,
|
TreeElement,
|
||||||
ToggleElement,
|
|
||||||
} from "../components/Installations/Log/CheckboxTree";
|
} from "../components/Installations/Log/CheckboxTree";
|
||||||
import { TimeRange, UnixTime } from "../dataCache/time";
|
import { TimeRange, UnixTime } from "../dataCache/time";
|
||||||
import { DataPoint, DataRecord } from "../dataCache/data";
|
import { DataPoint, DataRecord } from "../dataCache/data";
|
||||||
|
@ -143,7 +142,6 @@ export const extractTopologyValues = (
|
||||||
const values = topologyPaths[topologyKey as keyof TopologyValues].map(
|
const values = topologyPaths[topologyKey as keyof TopologyValues].map(
|
||||||
(topologyPath) => timeSeriesValue[topologyPath]
|
(topologyPath) => timeSeriesValue[topologyPath]
|
||||||
);
|
);
|
||||||
console.log("values", values, topologyKey);
|
|
||||||
switch (topologyKey as keyof TopologyValues) {
|
switch (topologyKey as keyof TopologyValues) {
|
||||||
case "gridToAcInConnection":
|
case "gridToAcInConnection":
|
||||||
topologyValues = [
|
topologyValues = [
|
||||||
|
@ -153,7 +151,6 @@ export const extractTopologyValues = (
|
||||||
default:
|
default:
|
||||||
topologyValues = values.map((element) => element.value);
|
topologyValues = values.map((element) => element.value);
|
||||||
}
|
}
|
||||||
console.log("topologyValues", topologyValues);
|
|
||||||
return {
|
return {
|
||||||
...acc,
|
...acc,
|
||||||
[topologyKey]: {
|
[topologyKey]: {
|
||||||
|
@ -198,10 +195,11 @@ export const parseCsv = (text: string): DataRecord => {
|
||||||
.map((l) => {
|
.map((l) => {
|
||||||
return l.split(";");
|
return l.split(";");
|
||||||
});
|
});
|
||||||
|
|
||||||
const x = y
|
const x = y
|
||||||
.map((fields) => {
|
.map((fields) => {
|
||||||
if (isNaN(Number(fields[1]))) {
|
if (fields[0] === "/AcDc/Warnings")
|
||||||
|
console.log("warnings", fields[1], isNaN(+fields[1]));
|
||||||
|
if (isNaN(Number(fields[1])) || fields[1] === "") {
|
||||||
return { [fields[0]]: { value: fields[1], unit: fields[2] } };
|
return { [fields[0]]: { value: fields[1], unit: fields[2] } };
|
||||||
}
|
}
|
||||||
return { [fields[0]]: { value: parseFloat(fields[1]), unit: fields[2] } };
|
return { [fields[0]]: { value: parseFloat(fields[1]), unit: fields[2] } };
|
||||||
|
@ -210,17 +208,6 @@ export const parseCsv = (text: string): DataRecord => {
|
||||||
return x;
|
return x;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const flattenToggles = (toggles: TreeElement[]): ToggleElement => {
|
|
||||||
return toggles.reduce((acc, current) => {
|
|
||||||
if (current.children.length > 0) {
|
|
||||||
acc[current.id] = false;
|
|
||||||
return { ...acc, ...flattenToggles(current.children) };
|
|
||||||
}
|
|
||||||
acc[current.id] = false;
|
|
||||||
return acc;
|
|
||||||
}, {} as ToggleElement);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const insertTreeElements = (
|
export const insertTreeElements = (
|
||||||
children: TreeElement[] = [],
|
children: TreeElement[] = [],
|
||||||
[head, ...tail]: string[]
|
[head, ...tail]: string[]
|
||||||
|
@ -291,7 +278,7 @@ export const transformToBarGraphData = (data: GraphCoordinates) => {
|
||||||
marker: { color: stringToColor(split) },
|
marker: { color: stringToColor(split) },
|
||||||
type: "bar",
|
type: "bar",
|
||||||
name: split,
|
name: split,
|
||||||
showlegend: !foundName,
|
showlegend: split.length > 0 ? !foundName : false,
|
||||||
} as any;
|
} as any;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue