diff --git a/csharp/InnovEnergy.sln b/csharp/InnovEnergy.sln
index 71a6f912e..d1ca70212 100644
--- a/csharp/InnovEnergy.sln
+++ b/csharp/InnovEnergy.sln
@@ -26,7 +26,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VenusLogger", "app/VenusLog
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meiringen", "app/Meiringen/Meiringen.csproj", "{4C816420-FD19-47BF-87FE-599210CA8384}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EmuMeterDriver", "app\EmuMeterDriver\EmuMeterDriver.csproj", "{F65F33B0-3522-4008-8D1E-47EF8E4C7AC7}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EmuMeterDriver", "app/EmuMeterDriver/EmuMeterDriver.csproj", "{F65F33B0-3522-4008-8D1E-47EF8E4C7AC7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BmsTunnel", "app/BmsTunnel/BmsTunnel.csproj", "{40B45363-BE34-420B-8F87-775EE6EE3513}"
EndProject
@@ -34,21 +34,19 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "app", "app", "{145597B4-3E3
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "lib", "lib", "{AD5B98A8-AB7F-4DA2-B66D-5B4E63E7D854}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "S3", "lib\S3\S3.csproj", "{C3639841-13F4-4F24-99C6-7D965593BF89}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "S3", "lib/S3/S3.csproj", "{C3639841-13F4-4F24-99C6-7D965593BF89}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "deprecated", "deprecated", "{D846B46B-46FF-4EF7-9B9D-DDBEF9533C56}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "deprecated", "deprecated", "{46DE03C4-52D1-47AA-8E60-8BB15361D723}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CsController", "app\CsController\CsController.csproj", "{72DBBE42-A09F-43C0-9613-331039857056}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CsController", "app/CsController/CsController.csproj", "{72DBBE42-A09F-43C0-9613-331039857056}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestBatteryDbus", "app\TestBatteryDbus\TestBatteryDbus.csproj", "{CB226D69-DD28-4AAF-8BBE-2488E37A0B8D}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SaliMax", "app/SaliMax/SaliMax.csproj", "{25073794-D859-4824-9984-194C7E928496}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SaliMax", "app\SaliMax\SaliMax.csproj", "{25073794-D859-4824-9984-194C7E928496}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GuiFeeder", "app/GuiFeeder/GuiFeeder.csproj", "{5B953EC4-51F3-4A0A-ADF5-BAA3D1570CB2}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GuiFeeder", "app\GuiFeeder\GuiFeeder.csproj", "{5B953EC4-51F3-4A0A-ADF5-BAA3D1570CB2}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatusApi", "lib\StatusApi\StatusApi.csproj", "{9D17E78C-8A70-43DB-A619-DC12D20D023D}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatusApi", "lib/StatusApi/StatusApi.csproj", "{9D17E78C-8A70-43DB-A619-DC12D20D023D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Devices", "Devices", "{4931A385-24DC-4E78-BFF4-356F8D6D5183}"
EndProject
@@ -58,38 +56,36 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Victron", "Victron", "{BD8C
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Trumpf", "Trumpf", "{DDDBEFD0-5DEA-4C7C-A9F2-FDB4636CF092}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TruConvert", "lib\Devices\Trumpf\TruConvert\TruConvert.csproj", "{EF46CF7B-823E-4CB7-966F-EDDC144C7954}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TruConvert", "lib/Devices/Trumpf/TruConvert/TruConvert.csproj", "{EF46CF7B-823E-4CB7-966F-EDDC144C7954}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TruConvertAc", "lib\Devices\Trumpf\TruConvertAc\TruConvertAc.csproj", "{1F4B445E-459E-44CD-813E-6D725EBB81E8}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TruConvertAc", "lib/Devices/Trumpf/TruConvertAc/TruConvertAc.csproj", "{1F4B445E-459E-44CD-813E-6D725EBB81E8}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TruConvertDc", "lib\Devices\Trumpf\TruConvertDc\TruConvertDc.csproj", "{F6F29829-C31A-4994-A698-E441BEA631C6}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TruConvertDc", "lib/Devices/Trumpf/TruConvertDc/TruConvertDc.csproj", "{F6F29829-C31A-4994-A698-E441BEA631C6}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DBus", "lib\Protocols\DBus\DBus.csproj", "{8C3C620A-087D-4DD6-B493-A47FC643F8DC}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DBus", "lib/Protocols/DBus/DBus.csproj", "{8C3C620A-087D-4DD6-B493-A47FC643F8DC}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Modbus", "lib\Protocols\Modbus\Modbus.csproj", "{E4AE6A33-0DEB-48EB-9D57-C0C7C63FC267}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Modbus", "lib/Protocols/Modbus/Modbus.csproj", "{E4AE6A33-0DEB-48EB-9D57-C0C7C63FC267}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VeDBus", "lib\Victron\VeDBus\VeDBus.csproj", "{50B26E29-1B99-4D07-BCA5-359CD550BBAA}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VeDBus", "lib/Victron/VeDBus/VeDBus.csproj", "{50B26E29-1B99-4D07-BCA5-359CD550BBAA}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VictronVRM", "lib\Victron\VictronVRM\VictronVRM.csproj", "{FE05DF69-B5C7-4C2E-8FB9-7776441A7622}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VictronVRM", "lib/Victron/VictronVRM/VictronVRM.csproj", "{FE05DF69-B5C7-4C2E-8FB9-7776441A7622}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ampt", "lib\Devices\AMPT\Ampt.csproj", "{77AF3A64-2878-4150-BCD0-F16530783165}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ampt", "lib/Devices/AMPT/Ampt.csproj", "{77AF3A64-2878-4150-BCD0-F16530783165}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Battery48TL", "lib\Devices\Battery48TL\Battery48TL.csproj", "{1C3F443A-B339-4B08-80E6-8A84817FFEC9}"
- ProjectSection(ProjectDependencies) = postProject
- {89A3E29C-4E57-47FE-A800-12AC68418264} = {89A3E29C-4E57-47FE-A800-12AC68418264}
- EndProjectSection
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Battery48TL", "lib/Devices/Battery48TL/Battery48TL.csproj", "{1C3F443A-B339-4B08-80E6-8A84817FFEC9}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EmuMeter", "lib\Devices\EmuMeter\EmuMeter.csproj", "{152A4168-F612-493C-BBEA-8EB26E6E2D34}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EmuMeter", "lib/Devices/EmuMeter/EmuMeter.csproj", "{152A4168-F612-493C-BBEA-8EB26E6E2D34}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Utils", "lib\Utils\Utils.csproj", "{89A3E29C-4E57-47FE-A800-12AC68418264}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Utils", "lib/Utils/Utils.csproj", "{89A3E29C-4E57-47FE-A800-12AC68418264}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Adam6060", "lib\Devices\Adam6060\Adam6060.csproj", "{4AFDB799-E6A4-4DCA-8B6D-8C0F98398461}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Adam6060", "lib/Devices/Adam6060/Adam6060.csproj", "{4AFDB799-E6A4-4DCA-8B6D-8C0F98398461}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Channels", "lib\Channels\Channels.csproj", "{AF7E8DCA-8D48-498E-AB3D-208061B244DC}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Channels", "lib/Channels/Channels.csproj", "{AF7E8DCA-8D48-498E-AB3D-208061B244DC}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Backend", "app\Backend\Backend.csproj", "{A56F58C2-B265-435B-A985-53B4D6F49B1A}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Backend", "app/Backend/Backend.csproj", "{A56F58C2-B265-435B-A985-53B4D6F49B1A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FossilTui", "app/FossilTui/FossilTui.csproj", "{C40264BB-C834-4C48-9B3F-6BEF8F37C0ED}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FossilTui", "app\FossilTui\FossilTui.csproj", "{C40264BB-C834-4C48-9B3F-6BEF8F37C0ED}"
EndProject
Global
diff --git a/csharp/app/EmuMeterDriver/EmuMeterDriver.csproj b/csharp/app/EmuMeterDriver/EmuMeterDriver.csproj
index da25cbeda..9132521ae 100644
--- a/csharp/app/EmuMeterDriver/EmuMeterDriver.csproj
+++ b/csharp/app/EmuMeterDriver/EmuMeterDriver.csproj
@@ -6,19 +6,15 @@
-
-
-
-
-
+
diff --git a/csharp/app/SaliMax/SaliMax.csproj b/csharp/app/SaliMax/SaliMax.csproj
index b4ff39371..52f0b084f 100644
--- a/csharp/app/SaliMax/SaliMax.csproj
+++ b/csharp/app/SaliMax/SaliMax.csproj
@@ -15,12 +15,16 @@
-
+
+
+
+
+
\ No newline at end of file
diff --git a/csharp/app/SaliMax/run (BeagleBone Meiringen).sh b/csharp/app/SaliMax/run (BeagleBone Meiringen).sh
index 962d2c1e7..e98675532 100755
--- a/csharp/app/SaliMax/run (BeagleBone Meiringen).sh
+++ b/csharp/app/SaliMax/run (BeagleBone Meiringen).sh
@@ -3,7 +3,6 @@
dotnet_version='net6.0'
-
set -e
echo -e "\n============================ Build ============================\n"
@@ -11,21 +10,28 @@ echo -e "\n============================ Build ============================\n"
dotnet publish \
./SaliMax.csproj \
-c Release \
- -r linux-arm
+ -r linux-x64
echo -e "\n============================ Deploy ============================\n"
rsync -v \
- ./bin/Release/$dotnet_version/linux-arm/publish/* \
- debian@10.2.1.87:~/salimax
+ ./bin/Release/$dotnet_version/linux-x64/publish/* \
+ ie-entwicklung@10.2.3.49:~/salimax
+
+
+ # debian@10.2.1.87:~/salimax
-echo -e "\n============================ Run ============================\n"
+echo -e "\n============================ Restart Salimax sevice ============================\n"
ssh -tt \
- -o StrictHostKeyChecking=no \
- -o UserKnownHostsFile=/dev/null \
- -o ConnectTimeout=2 \
- debian@10.2.1.87 \
- '~/salimax/SaliMax' \
- 2>/dev/null
+ ie-entwicklung@10.2.3.49 \
+ sudo systemctl restart salimax.service
+
+
+echo -e "\n============================ Print service output ============================\n"
+
+ssh -tt \
+ ie-entwicklung@10.2.3.49 \
+ journalctl -f -u salimax.service
+
diff --git a/csharp/app/SaliMax/src/Controller/Control.cs b/csharp/app/SaliMax/src/Controller/Control.cs
index b730fdfec..144e2b166 100644
--- a/csharp/app/SaliMax/src/Controller/Control.cs
+++ b/csharp/app/SaliMax/src/Controller/Control.cs
@@ -13,14 +13,14 @@ public static class Control
public static Decimal ControlInverterPower(this StatusRecord status, Decimal targetInverterPower)
{
var s = status.InverterStatus!;
- var totalInverterAcPower = s.PowerAcL1 + s.PowerAcL2 + s.PowerAcL3;
+ var totalInverterAcPower = s.Ac.ActivePower;
return ControlPower(totalInverterAcPower, targetInverterPower,status.SalimaxConfig!.PConstant);
}
- public static Decimal ControlBatteryPower(this StatusRecord status, Decimal targetBatteryPower)
+ public static Decimal ControlBatteryPower(this StatusRecord status, Decimal targetBatteryPower, UInt16 i = 0) //this will use the avg batteries
{
- return ControlPower(status.BatteryStatus!.Power, targetBatteryPower, status.SalimaxConfig!.PConstant);
+ return ControlPower(status.BatteriesStatus![i].Dc.Power, targetBatteryPower, status.SalimaxConfig!.PConstant);
}
public static Decimal ControlLowBatterySoc(this StatusRecord status)
@@ -31,14 +31,14 @@ public static class Control
public static Decimal LowerLimit(params Decimal[] deltas) => deltas.Max();
public static Decimal UpperLimit(params Decimal[] deltas) => deltas.Min();
- private static Decimal HoldMinSocCurve(StatusRecord s)
+ private static Decimal HoldMinSocCurve(StatusRecord s, UInt16 i = 0)
{
// TODO: explain LowSOC curve
var a = -2 * s.SalimaxConfig!.SelfDischargePower / s.SalimaxConfig.HoldSocZone;
var b = -a * (s.SalimaxConfig.MinSoc + s.SalimaxConfig.HoldSocZone);
- return s.BatteryStatus!.Soc * a + b;
+ return s.BatteriesStatus![i].Soc * a + b; //this will use the avg batteries
}
private static Decimal ControlPower(Decimal measurement, Decimal target, Decimal p)
diff --git a/csharp/app/SaliMax/src/Controller/Controller.cs b/csharp/app/SaliMax/src/Controller/Controller.cs
index 3165a9f86..e578c5b2d 100644
--- a/csharp/app/SaliMax/src/Controller/Controller.cs
+++ b/csharp/app/SaliMax/src/Controller/Controller.cs
@@ -18,7 +18,7 @@ public static class Controller
private static readonly TimeSpan CommunicationTimeout = TimeSpan.FromSeconds(10);
- private static readonly Int16 MaxmimumAllowedBatteryTemp = 315;
+ public static readonly Int16 MaxmimumAllowedBatteryTemp = 315;
private static UInt16 _numberOfInverters;
@@ -71,7 +71,7 @@ public static class Controller
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
} => 9,
{
- SaliMaxRelayStatus.K1: Open, SaliMaxRelayStatus.K2: Open, SaliMaxRelayStatus.K3: Closed,
+ SaliMaxRelayStatus.K1: Closed, SaliMaxRelayStatus.K2: Open, SaliMaxRelayStatus.K3: Open,
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
} => 10,
{
@@ -79,11 +79,11 @@ public static class Controller
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
} => 11,
{
- SaliMaxRelayStatus.K1: Open, SaliMaxRelayStatus.K2: Closed, SaliMaxRelayStatus.K3: Closed,
+ SaliMaxRelayStatus.K1: Closed, SaliMaxRelayStatus.K2: Closed, SaliMaxRelayStatus.K3: Open,
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
} => 12,
{
- SaliMaxRelayStatus.K1: Closed, SaliMaxRelayStatus.K2: Open, SaliMaxRelayStatus.K3: Open,
+ SaliMaxRelayStatus.K1: Open, SaliMaxRelayStatus.K2: Open, SaliMaxRelayStatus.K3: Closed,
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
} => 13,
{
@@ -91,7 +91,7 @@ public static class Controller
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
} => 14,
{
- SaliMaxRelayStatus.K1: Closed, SaliMaxRelayStatus.K2: Closed, SaliMaxRelayStatus.K3: Open,
+ SaliMaxRelayStatus.K1: Open, SaliMaxRelayStatus.K2: Closed, SaliMaxRelayStatus.K3: Closed,
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
} => 15,
{
@@ -140,7 +140,10 @@ public static class Controller
public static ControlRecord SaliMaxControl(StatusRecord statusRecord)
{
- var resetInverterAlarm = CheckInverterAlarms(statusRecord);
+ var currentSaliMaxState = GetSaliMaxState(statusRecord);
+
+ UInt16 acSlaveId = 1;
+ var resetInverterAlarm = CheckInverterAlarms(statusRecord, currentSaliMaxState).WriteLine(" reset Alarm");
var resetDcAlarm = CheckDcDcAlarms(statusRecord);
var lastEocTime = GetLastEocTime(statusRecord);
@@ -151,33 +154,49 @@ public static class Controller
var noGridMeter = statusRecord.GridMeterStatus == null;
var saliMaxConfig = statusRecord.SalimaxConfig with { LastEoc = lastEocTime };
-
- var currentSaliMaxState = GetSaliMaxState(statusRecord);
+
ExplainState(currentSaliMaxState);
-
+
const RelayState k2Relay = Closed;
- var acPowerStageEnable = StateConfig.AcPowerStageEnableStates.Contains(currentSaliMaxState) || currentSaliMaxState == 8;
+ var acPowerStageEnable = StateConfig.AcPowerStageEnableStates.Contains(currentSaliMaxState); //this is logical incorrect, find better way
+
+ var dcPowerStageEnable = statusRecord.BatteriesStatus is not null; // TODO this is to check, Can be the batteries Status be null?
- var dcPowerStageEnable = statusRecord.BatteryStatus is not null; // this is to check
+ var salimaxRelay = statusRecord.SaliMaxRelayStatus! with { K2 = k2Relay }; // to check // this is must be control
- var salimaxRelay = statusRecord.SaliMaxRelayStatus! with { K2 = k2Relay }; // to check
-
-
- if (statusRecord.BatteryStatus == null)
+ if (resetInverterAlarm)
{
+ acPowerStageEnable = !resetInverterAlarm ;
+ acSlaveId = 0;
+ }
+
+ if (resetDcAlarm)
+ {
+ dcPowerStageEnable = !resetDcAlarm ;
+ }
+
+ acSlaveId.WriteLine(" AcSlave @");
+
+ if (statusRecord.BatteriesStatus == null)
+ {
+ Console.WriteLine(" No batteries");
return new ControlRecord
{
AcControlRecord = Defaults.TruConvertAcControl with
{
SignedPowerNominalValue = 0,
PowerStageEnable = acPowerStageEnable,
+ CommunicationTimeout = CommunicationTimeout,
+ SlaveAddress = acSlaveId,
ResetsAlarmAndWarning = resetInverterAlarm
},
DcControlRecord = Defaults.TruConvertDcControl with
{
- PowerStageEnable = dcPowerStageEnable,
- ResetsAlarmAndWarning = resetDcAlarm
+ PowerStageEnable = dcPowerStageEnable,
+ ResetsAlarmAndWarning = resetDcAlarm,
+ TimeoutForCommunication = CommunicationTimeout
+
},
SalimaxConfig = saliMaxConfig, // must create a control of each
SalimaxRelays = salimaxRelay, // must create a control of each
@@ -201,6 +220,38 @@ public static class Controller
throw new NotImplementedException();
}
+ var newPowerSetPoint = CalculateNewPowerSetPoint(statusRecord);
+
+ ////////////////////////// Control Record //////////////////////////
+
+ var acControlRecord = Defaults.TruConvertAcControl with
+ {
+ PowerStageEnable = acPowerStageEnable,
+ CommunicationTimeout = CommunicationTimeout,
+ SignedPowerNominalValue = newPowerSetPoint,
+ SlaveAddress = acSlaveId,
+ ResetsAlarmAndWarning = resetInverterAlarm
+ };
+
+ var dcControlRecord = Defaults.TruConvertDcControl with
+ {
+ PowerStageEnable = dcPowerStageEnable,
+ ResetsAlarmAndWarning = resetDcAlarm,
+ TimeoutForCommunication = CommunicationTimeout
+ };
+
+
+ return new ControlRecord
+ {
+ AcControlRecord = acControlRecord,
+ DcControlRecord = dcControlRecord,
+ SalimaxConfig = saliMaxConfig,
+ SalimaxRelays = salimaxRelay
+ };
+ }
+
+ private static Decimal CalculateNewPowerSetPoint(StatusRecord statusRecord)
+ {
var currentPowerSetPoint = statusRecord.InverterStatus!.AcSignedPowerValue;
var limitReason = "no limit";
@@ -212,7 +263,7 @@ public static class Controller
goal = "Calibration Charge";
delta = statusRecord.ControlInverterPower(statusRecord.SalimaxConfig.MaxInverterPower);
}
- else if (statusRecord.BatteryStatus!.Soc < statusRecord.SalimaxConfig.MinSoc)
+ else if (statusRecord.AvgBatteriesStatus!.Soc < statusRecord.SalimaxConfig.MinSoc) // TODO
{
goal = $"reach min SOC (Min soc: {statusRecord.SalimaxConfig.MinSoc})";
delta = statusRecord.ControlInverterPower(statusRecord.SalimaxConfig
@@ -234,7 +285,7 @@ public static class Controller
delta = inverterAc2DcLimitPower;
}
- var batteryChargingLimitPower = statusRecord.ControlBatteryPower(statusRecord.BatteryStatus!.MaxChargingPower);
+ var batteryChargingLimitPower = statusRecord.ControlBatteryPower(statusRecord.BatteriesStatus[0]!.MaxChargingPower);
if (delta > batteryChargingLimitPower)
{
@@ -253,12 +304,12 @@ public static class Controller
}
var batteryDischargingLimitPower =
- statusRecord.ControlBatteryPower(statusRecord.BatteryStatus!.MaxDischargingPower);
+ statusRecord.ControlBatteryPower(statusRecord.BatteriesStatus[0]!.MaxDischargingPower); // TODO change to avg battery
if (delta < batteryDischargingLimitPower)
{
limitReason =
- $"limited by max battery discharging power: {statusRecord.BatteryStatus!.MaxDischargingPower}";
+ $"limited by max battery discharging power: {statusRecord.BatteriesStatus[0]!.MaxDischargingPower}";// TODO change to avg battery
delta = batteryDischargingLimitPower;
}
@@ -271,13 +322,13 @@ public static class Controller
delta = keepMinSocLimitDelta;
}
- /* if (statusRecord.BatteryStatus.BatteryTemperature >= 300) must not reduce the delta
- {
- var softLandingFactor = (MaxmimumAllowedBatteryTemp - statusRecord.BatteryStatus.BatteryTemperature) / 15; //starting softlanding from 300 degree
- limitReason =
- $"limiting discharging power in order to stay keep the battery temp below 315°: {statusRecord.BatteryStatus.BatteryTemperature}°" + " Softlanding factor: " + softLandingFactor;
- delta *= softLandingFactor;
- }*/
+ // if (statusRecord.BatteriesStatus[0]!.Temperature >= 300) //must not reduce the delta
+ // {
+ // var softLandingFactor = (MaxmimumAllowedBatteryTemp - statusRecord.BatteriesStatus[0]!.Temperature) / 15; //starting softlanding from 300 degree
+ // limitReason =
+ // $"limiting discharging power in order to stay keep the battery temp below 315°: {statusRecord.BatteriesStatus[0]!.Temperature}°" + " Softlanding factor: " + softLandingFactor;
+ // delta *= softLandingFactor;
+ // }
var newPowerSetPoint =
DistributePower(currentPowerSetPoint + delta, statusRecord.SalimaxConfig.MaxInverterPower);
@@ -289,32 +340,7 @@ public static class Controller
limitReason.WriteLine(" Limit reason");
delta.WriteLine(" Delta");
// "============".WriteLine();
-
- ////////////////////////// Control Record //////////////////////////
-
- var acControlRecord = Defaults.TruConvertAcControl with
- {
- PowerStageEnable = acPowerStageEnable,
- CommunicationTimeout = CommunicationTimeout,
- SignedPowerNominalValue = newPowerSetPoint,
- ResetsAlarmAndWarning = resetInverterAlarm
- };
-
- var dcControlRecord = Defaults.TruConvertDcControl with
- {
- PowerStageEnable = dcPowerStageEnable,
- ResetsAlarmAndWarning = resetDcAlarm,
- TimeoutForCommunication = CommunicationTimeout
- };
-
-
- return new ControlRecord
- {
- AcControlRecord = acControlRecord,
- DcControlRecord = dcControlRecord,
- SalimaxConfig = saliMaxConfig,
- SalimaxRelays = salimaxRelay
- };
+ return newPowerSetPoint;
}
private static State TargetState(State currentState)
@@ -423,7 +449,7 @@ public static class Controller
private static UnixTime GetLastEocTime(StatusRecord statusRecord)
{
- if (statusRecord.BatteryStatus?.Soc >= 100)
+ if (statusRecord.BatteriesStatus[0]!.Soc >= 100 && statusRecord.BatteriesStatus[1]!.Soc >= 100 )
{
Console.WriteLine("battery has reached EOC");
File.AppendAllTextAsync(Config.LogSalimaxLog, String.Join(Environment.NewLine, UnixTime.Now + "battery has reached EOC"));
@@ -442,6 +468,7 @@ public static class Controller
private static Boolean CheckDcDcAlarms(StatusRecord s)
{
+ s.DcDcStatus?.Alarms.Count.WriteLine(" Dc Alarm count");
if ( s.DcDcStatus?.Alarms.Count > 0 &&
s.DcDcStatus?.PowerOperation == false)
{
@@ -452,14 +479,15 @@ public static class Controller
return false;
}
- private static Boolean CheckInverterAlarms(StatusRecord s)
+ private static Boolean CheckInverterAlarms(StatusRecord s, UInt16 state)
{
- if ( s.InverterStatus?.Alarms.Count > 0 &&
- s.InverterStatus?.PowerOperation == false)
+ s.InverterStatus?.Alarms.Count.WriteLine(" Ac Alarm count");
+ if ( s.InverterStatus?.Alarms.Count > 0 )
{
- File.AppendAllTextAsync(Config.LogSalimaxLog, UnixTime.Now + " " + s.InverterStatus.Alarms);
+ File.AppendAllTextAsync(Config.LogSalimaxLog, UnixTime.Now + " " + s.InverterStatus.Alarms[0]); // Todo write every alarm in he alarm list
return true;
}
+
return false;
}
diff --git a/csharp/app/SaliMax/src/Controller/State.cs b/csharp/app/SaliMax/src/Controller/State.cs
index 357d5410c..a8ad8d11b 100644
--- a/csharp/app/SaliMax/src/Controller/State.cs
+++ b/csharp/app/SaliMax/src/Controller/State.cs
@@ -5,14 +5,26 @@ public enum State : Int16
{
State1 = 1,
State2 = 2,
+ State3 = 3,
State4 = 4,
+ State5 = 5,
State6 = 6,
+ State7 = 7,
+ State8 = 8,
State9 = 9,
+ State10 = 10,
+ State11 = 11,
State12 = 12,
State13 = 13,
+ State14 = 14,
State15 = 15,
State16 = 16,
State17 = 17,
+ State18 = 18,
+ State19 = 19,
+ State20 = 20,
State21 = 21,
State22 = 22,
+ State23 = 23,
+ State24 = 24
}
\ No newline at end of file
diff --git a/csharp/app/SaliMax/src/Controller/StateConfig.cs b/csharp/app/SaliMax/src/Controller/StateConfig.cs
index c2ae6065d..be40aafc0 100644
--- a/csharp/app/SaliMax/src/Controller/StateConfig.cs
+++ b/csharp/app/SaliMax/src/Controller/StateConfig.cs
@@ -3,5 +3,5 @@ namespace InnovEnergy.SaliMax.Controller;
public static class StateConfig
{
- public static readonly IReadOnlyList AcPowerStageEnableStates = new[] { 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 };
+ public static readonly IReadOnlyList AcPowerStageEnableStates = new[] {8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 };
}
\ No newline at end of file
diff --git a/csharp/app/SaliMax/src/Controller/StatusRecord.cs b/csharp/app/SaliMax/src/Controller/StatusRecord.cs
index 7842aa845..0969b841b 100644
--- a/csharp/app/SaliMax/src/Controller/StatusRecord.cs
+++ b/csharp/app/SaliMax/src/Controller/StatusRecord.cs
@@ -10,13 +10,13 @@ namespace InnovEnergy.SaliMax.Controller;
public record StatusRecord
{
- public TruConvertAcStatus? InverterStatus { get; init; }
- public TruConvertDcStatus? DcDcStatus { get; init; }
- public Battery48TLStatus? BatteryStatus { get; init; }
- public EmuMeterStatus? GridMeterStatus { get; init; }
- public SaliMaxRelayStatus? SaliMaxRelayStatus { get; init; }
- public AmptStatus? AmptStatus { get; init; }
- public EmuMeterStatus? AcInToAcOutMeterStatus { get; init; }
- public SalimaxConfig SalimaxConfig { get; init; } = null!;
-}
-
\ No newline at end of file
+ public TruConvertAcStatus? InverterStatus { get; init; }
+ public TruConvertDcStatus? DcDcStatus { get; init; }
+ public Battery48TLStatus[]? BatteriesStatus { get; set; } = Array.Empty(); // TODO remove static
+ public AvgBatteriesStatus? AvgBatteriesStatus { get; init; }
+ public EmuMeterStatus? GridMeterStatus { get; init; }
+ public SaliMaxRelayStatus? SaliMaxRelayStatus { get; init; }
+ public AmptStatus? AmptStatus { get; init; }
+ public EmuMeterStatus? AcInToAcOutMeterStatus { get; init; }
+ public SalimaxConfig SalimaxConfig { get; init; } = null!;
+}
\ No newline at end of file
diff --git a/csharp/app/SaliMax/src/Log/Ampt.cs b/csharp/app/SaliMax/src/Log/Ampt.cs
index d250a01bd..1a63b9eab 100644
--- a/csharp/app/SaliMax/src/Log/Ampt.cs
+++ b/csharp/app/SaliMax/src/Log/Ampt.cs
@@ -10,16 +10,17 @@ public static class Ampt
{
if (s is null)
return null;
+
+ // TODO return one AMPT device to sum all the other
return DeviceType
.PvOnDc
.CreateDevice("AMPT")
- .AddProp("Current 1", s.Current1)
- .AddProp("Current 2", s.Current2)
- .AddProp("Voltage 1", s.Voltage1)
- .AddProp("Voltage 2", s.Voltage2)
- .AddProp("Power 1", s.Current1 * s.Voltage1)
- .AddProp("Power 2", s.Current2 * s.Voltage2);
- // .AddDcConnection(s.AvgCurrent.Round3(), s.AvgVolatge.Round3());
+ .AddProp("Current 1", s.Devices[0].Dc.Current)
+ .AddProp("Current 2", s.Devices[1].Dc.Current)
+ .AddProp("Voltage 1", s.Devices[0].Dc.Voltage)
+ .AddProp("Voltage 2", s.Devices[1].Dc.Voltage)
+ .AddProp("Power 1", s.Devices[0].Dc.Current * s.Devices[0].Dc.Voltage)
+ .AddProp("Power 2", s.Devices[1].Dc.Current * s.Devices[1].Dc.Voltage);
}
}
\ No newline at end of file
diff --git a/csharp/app/SaliMax/src/Log/Battery48Tl.cs b/csharp/app/SaliMax/src/Log/Battery48Tl.cs
index 612ea6e28..db755c78d 100644
--- a/csharp/app/SaliMax/src/Log/Battery48Tl.cs
+++ b/csharp/app/SaliMax/src/Log/Battery48Tl.cs
@@ -14,13 +14,13 @@ public static class Battery48Tl
return DeviceType
.Battery
.CreateDevice("48TL Battery")
- .AddDc48Connection(s.Current.Round3(),s.Voltage.Round3())
+ .AddDc48Connection(s.Dc.Current.Round3(),s.Dc.Voltage.Round3())
.AddAlarms(s.Alarms)
.AddWarnings(s.Warnings)
.AddProp("Soc", s.Soc.Round3())
.AddProp("HeaterOn", s.HeaterOn)
.AddProp("EocReached", s.EocReached)
.AddProp("BatteryCold", s.BatteryCold)
- .AddProp("Temperature", s.BatteryTemperature);
+ .AddProp("Temperature", s.Temperature);
}
}
\ No newline at end of file
diff --git a/csharp/app/SaliMax/src/Log/EmuMeter.cs b/csharp/app/SaliMax/src/Log/EmuMeter.cs
index a6b7062cf..8b61199cf 100644
--- a/csharp/app/SaliMax/src/Log/EmuMeter.cs
+++ b/csharp/app/SaliMax/src/Log/EmuMeter.cs
@@ -17,16 +17,16 @@ public static class EmuMeter
//
- var l1 = CreateAcPhase(s.CurrentL1, s.VoltageL1N, ACos(s.PowerFactorL1));
- var l2 = CreateAcPhase(s.CurrentL2, s.VoltageL2N, ACos(s.PowerFactorL2));
- var l3 = CreateAcPhase(s.CurrentL3, s.VoltageL3N, ACos(s.PowerFactorL3));
+ var l1 = CreateAcPhase(s.Ac.L1.Current, s.Ac.L1.Voltage, ACos(s.Ac.L1.PowerFactor));
+ var l2 = CreateAcPhase(s.Ac.L2.Current, s.Ac.L2.Voltage, ACos(s.Ac.L2.PowerFactor));
+ var l3 = CreateAcPhase(s.Ac.L3.Current, s.Ac.L3.Voltage, ACos(s.Ac.L3.PowerFactor));
var ac = new JsonObject
{
["L1"] = l1,
["L2"] = l2,
["L3"] = l3,
- ["Frequency"] = s.Frequency
+ ["Frequency"] = s.Ac.Frequency
};
var status = new JsonObject
@@ -39,8 +39,8 @@ public static class EmuMeter
private static IEnumerable GetAcPhases(this EmuMeterStatus s)
{
- yield return CreateAcPhase(s.CurrentL1.Round3(),s.VoltageL1N.Round3(),s.PowerFactorL1.Apply(ACos).Round3());
- yield return CreateAcPhase(s.CurrentL2.Round3(),s.VoltageL2N.Round3(),s.PowerFactorL2.Apply(ACos).Round3());
- yield return CreateAcPhase(s.CurrentL3.Round3(),s.VoltageL3N.Round3(),s.PowerFactorL3.Apply(ACos).Round3());
+ yield return CreateAcPhase(s.Ac.L1.Current.Round3(),s.Ac.L1.Voltage.Round3(),s.Ac.L1.PowerFactor.Apply(ACos).Round3());
+ yield return CreateAcPhase(s.Ac.L2.Current.Round3(),s.Ac.L2.Voltage.Round3(),s.Ac.L2.PowerFactor.Apply(ACos).Round3());
+ yield return CreateAcPhase(s.Ac.L3.Current.Round3(),s.Ac.L3.Voltage.Round3(),s.Ac.L3.PowerFactor.Apply(ACos).Round3());
}
}
\ No newline at end of file
diff --git a/csharp/app/SaliMax/src/Log/Salimax.cs b/csharp/app/SaliMax/src/Log/Salimax.cs
index 00ff996d8..76bd25648 100644
--- a/csharp/app/SaliMax/src/Log/Salimax.cs
+++ b/csharp/app/SaliMax/src/Log/Salimax.cs
@@ -24,15 +24,16 @@ public static class Salimax
private static IEnumerable GetDevices(StatusRecord s)
{
- yield return s.InverterStatus.Log("1234");
+ yield return s.InverterStatus.Log();
yield return s.DcDcStatus.Log("3214");
- yield return s.GridMeterStatus.Log(DeviceType.Grid);
- yield return s.AcInToAcOutMeterStatus.Log(DeviceType.AcInToAcOut);
+ yield return s.GridMeterStatus.Log(DeviceType.Grid , "123");
+ yield return s.AcInToAcOutMeterStatus.Log(DeviceType.AcInToAcOut, "123");
yield return s.AmptStatus.Log();
- yield return s.BatteryStatus.Log();
+ yield return s.BatteriesStatus![0].Log();
+ yield return s.BatteriesStatus[1].Log();
}
- public static JsonArray CreateTopology()
+ private static JsonArray CreateTopology()
{
var acInBusJson = JsonUtil.CreateBus
(
diff --git a/csharp/app/SaliMax/src/Log/TruConvertAc.cs b/csharp/app/SaliMax/src/Log/TruConvertAc.cs
index 9a0446a66..eeb56ea4c 100644
--- a/csharp/app/SaliMax/src/Log/TruConvertAc.cs
+++ b/csharp/app/SaliMax/src/Log/TruConvertAc.cs
@@ -9,13 +9,12 @@ namespace InnovEnergy.SaliMax.Log;
public static class TruConvertAc
{
- // TODO: remove serialNb arg, embed TruConvertDcStatus
- public static JsonObject? Log(this TruConvertAcStatus? s, String serialNb)
+ public static JsonObject? Log(this TruConvertAcStatus? s)
{
if (s is null)
return null;
-
- var dcPower = s.PowerAcL1 + s.PowerAcL2 + s.PowerAcL3;
+
+ var dcPower = s.Ac.ActivePower;
var dcVoltage = s.ActualDcLinkVoltageLowerHalfExt + s.ActualDcLinkVoltageUpperHalfExt;
var dcCurrent = dcVoltage != 0m
? dcPower / dcVoltage
@@ -25,16 +24,16 @@ public static class TruConvertAc
// TODO: acos quadrant
// TODO: total AC power
- var l1 = CreateAcPhase(s.PhaseCurrentL1, s.GridVoltageL1, ACos(s.CosPhiL1));
- var l2 = CreateAcPhase(s.PhaseCurrentL2, s.GridVoltageL2, ACos(s.CosPhiL2));
- var l3 = CreateAcPhase(s.PhaseCurrentL3, s.GridVoltageL3, ACos(s.CosPhiL3));
+ var l1 = CreateAcPhase(s.Ac.L1.Current.Round3(), s.Ac.L1.Voltage.Round3(), s.Ac.L1.PowerFactor.Clamp(-1m, 1m).Apply(ACos).Round3());
+ var l2 = CreateAcPhase(s.Ac.L2.Current.Round3(), s.Ac.L2.Voltage.Round3(), s.Ac.L1.PowerFactor.Clamp(-1m, 1m).Apply(ACos).Round3());
+ var l3 = CreateAcPhase(s.Ac.L3.Current.Round3(), s.Ac.L3.Voltage.Round3(), s.Ac.L1.PowerFactor.Clamp(-1m, 1m).Apply(ACos).Round3());
var ac = new JsonObject
{
["L1"] = l1,
["L2"] = l2,
["L3"] = l3,
- ["Frequency"] = s.GridFrequency
+ ["Frequency"] = s.Ac.Frequency
};
var dc = CreateDcPhase(dcCurrent, dcVoltage);
@@ -47,20 +46,20 @@ public static class TruConvertAc
["Alarms"] = s.Alarms.ToJsonArray() ,
};
- return new JsonObject { [$"TruConvertAc {serialNb}"] = status };
+ return new JsonObject { [$"TruConvertAc {s.SerialNumber}"] = status };
}
private static IEnumerable GetAcPhases(this TruConvertAcStatus s)
{
// Math.Acos return "NaN" if the cos phi < -1 or > 1
// Decimal.Acos throw an exception
- yield return JsonUtil.CreateAcPhase(s.PhaseCurrentL1.Round3(), s.GridVoltageL1.Round3(),
- s.CosPhiL1.Clamp(-1m, 1m).Apply(ACos).Round3());
+ yield return JsonUtil.CreateAcPhase(s.Ac.L1.Current.Round3(), s.Ac.L1.Voltage.Round3(),
+ s.Ac.L1.PowerFactor.Clamp(-1m, 1m).Apply(ACos).Round3());
- yield return JsonUtil.CreateAcPhase(s.PhaseCurrentL2.Round3(), s.GridVoltageL2.Round3(),
- s.CosPhiL2.Clamp(-1m, 1m).Apply(ACos).Round3());
+ yield return JsonUtil.CreateAcPhase(s.Ac.L2.Current.Round3(), s.Ac.L2.Voltage.Round3(),
+ s.Ac.L2.PowerFactor.Clamp(-1m, 1m).Apply(ACos).Round3());
- yield return JsonUtil.CreateAcPhase(s.PhaseCurrentL3.Round3(), s.GridVoltageL3.Round3(),
- s.CosPhiL3.Clamp(-1m, 1m).Apply(ACos).Round3());
+ yield return JsonUtil.CreateAcPhase(s.Ac.L3.Current.Round3(), s.Ac.L3.Voltage.Round3(),
+ s.Ac.L3.PowerFactor.Clamp(-1m, 1m).Apply(ACos).Round3());
}
}
\ No newline at end of file
diff --git a/csharp/app/SaliMax/src/Log/TruConvertDc.cs b/csharp/app/SaliMax/src/Log/TruConvertDc.cs
index 68536c609..09e39d1f2 100644
--- a/csharp/app/SaliMax/src/Log/TruConvertDc.cs
+++ b/csharp/app/SaliMax/src/Log/TruConvertDc.cs
@@ -14,30 +14,19 @@ public static class TruConvertDc
if (s is null)
return null;
- var dcCurrent = s.DcLinkVoltage != 0m
- ? s.DcPower / s.DcLinkVoltage
- : 0m;
+ var dcCurrent = s.Dc.Current;
return new JO
{
{
$"TruConvertDc {serialNb}", new JO
{
- { "Dc" , CreateDcPhase(dcCurrent, s.DcLinkVoltage) },
+ { "Dc" , CreateDcPhase(dcCurrent, s.Dc.Voltage) },
{ "Dc48" , CreateDcPhase(s.BatteryCurrent, s.BatteryVoltage) },
{ "Warnings", s.Warnings.ToJsonArray() },
{ "Alarms" , s.Alarms.ToJsonArray() },
}
}
};
-
- // return DeviceType
- // .DcDc
- // .CreateDevice("TruConvertDc")
- // //.AddDcConnection(Decimal.Round(current, 3), s.DcLinkVoltage)
- // .AddDc48Connection(Decimal.Round(s.BatteryCurrent, 3), Decimal.Round(s.BatteryVoltage, 3))
- // .AddWarnings(s.Warnings)
- // .AddAlarms(s.Alarms)
- // .AddProp("DC Power", s.DcPower);
}
}
\ No newline at end of file
diff --git a/csharp/app/SaliMax/src/Program.cs b/csharp/app/SaliMax/src/Program.cs
index aba4509a4..1bbbc8883 100644
--- a/csharp/app/SaliMax/src/Program.cs
+++ b/csharp/app/SaliMax/src/Program.cs
@@ -1,3 +1,6 @@
+#undef BatteriesAllowed
+
+
using System.Diagnostics;
using System.Text.Json;
using System.Text.Json.Nodes;
@@ -14,15 +17,18 @@ using InnovEnergy.SaliMax.Log;
using InnovEnergy.SaliMax.SaliMaxRelays;
using InnovEnergy.SaliMax.SystemConfig;
using InnovEnergy.Time.Unix;
-
+using Utils = InnovEnergy.Lib.StatusApi.Utils;
+
+
#pragma warning disable IL2026
+
namespace InnovEnergy.SaliMax;
internal static class Program
{
private const UInt32 UpdateIntervalSeconds = 2;
-
+
public static async Task Main(String[] args)
{
try
@@ -31,7 +37,8 @@ internal static class Program
}
catch (Exception e)
{
- await File.AppendAllTextAsync(Config.LogSalimaxLog, String.Join(Environment.NewLine, UnixTime.Now + " \n" + e));
+ await File.AppendAllTextAsync(Config.LogSalimaxLog,
+ String.Join(Environment.NewLine, UnixTime.Now + " \n" + e));
throw;
}
}
@@ -51,33 +58,58 @@ internal static class Program
};
#if DEBUG
- var inverterDevice = new TruConvertAcDevice("127.0.0.1", 5001);
- var dcDcDevice = new TruConvertDcDevice("127.0.0.1", 5002);
- var gridMeterDevice = new EmuMeterDevice("127.0.0.1", 5003);
- var saliMaxRelaysDevice = new SaliMaxRelaysDevice("127.0.0.1", 5004);
- var amptDevice = new AmptCommunicationUnit("127.0.0.1", 5005);
+ var inverterDevice = new TruConvertAcDevice("127.0.0.1", 5001);
+ var dcDcDevice = new TruConvertDcDevice("127.0.0.1", 5002);
+ var gridMeterDevice = new EmuMeterDevice("127.0.0.1", 5003);
+ var saliMaxRelaysDevice = new SaliMaxRelaysDevice("127.0.0.1", 5004);
+ var amptDevice = new AmptCommunicationUnit("127.0.0.1", 5005);
var acInToAcOutMeterDevice = new EmuMeterDevice("127.0.0.1", 5003); // TODO: use real device
- var battery48TlDevice = Battery48TlDevice.Fake();
- var salimaxConfig = new SalimaxConfig();
-#else
- var battery48TlDevice = new Battery48TlDevice("/dev/ttyUSB0", 3);
- var inverterDevice = new TruConvertAcDevice("192.168.1.2");
- var dcDcDevice = new TruConvertDcDevice("192.168.1.3");
- var gridMeterDevice = new EmuMeterDevice("192.168.1.241");
- var acInToAcOutMeterDevice = new EmuMeterDevice("192.168.1.241"); // TODO: use real device
- var amptDevice = new AmptCommunicationUnit("192.168.1.249");
- var saliMaxRelaysDevice = new SaliMaxRelaysDevice("192.168.1.242");
+ var secondBattery48TlDevice = Battery48TlDevice.Fake();
+ var firstBattery48TlDevice =Battery48TlDevice.Fake();;
var salimaxConfig = new SalimaxConfig();
+#else
+#if BatteriesAllowed
+ var firstBattery48TlDevice = new Battery48TlDevice("/dev/ttyUSB0", 2);
+ var secondBattery48TlDevice = new Battery48TlDevice("/dev/ttyUSB0", 3);
+#endif
+ var inverterDevice = new TruConvertAcDevice("192.168.1.2");
+ var dcDcDevice = new TruConvertDcDevice("192.168.1.3");
+ var gridMeterDevice = new EmuMeterDevice("192.168.1.241");
+ var acInToAcOutMeterDevice = new EmuMeterDevice("192.168.1.241"); // TODO: use real device
+ var amptDevice = new AmptCommunicationUnit("192.168.1.249");
+ var saliMaxRelaysDevice = new SaliMaxRelaysDevice("192.168.1.242");
+ var salimaxConfig = new SalimaxConfig();
+#endif
+ // This is will be always add manually ? or do we need to read devices automatically in a range of IP @
+#if BatteriesAllowed
+
+ var battery48TlDevices = new[] { firstBattery48TlDevice, secondBattery48TlDevice };
#endif
-
+ var dcDcDevices = new[] { dcDcDevice };
+ var inverterDevices = new[] { inverterDevice};
+
StatusRecord ReadStatus()
{
+#if BatteriesAllowed
+
+ var battery48TlStatusArray = battery48TlDevices.Select(b => b.ReadStatus()).NotNull().ToArray();
+#endif
+ // var dcDcStatusArray = dcDcDevices.Select(b => b.ReadStatus()).NotNull().ToArray();
+ // var inverterStatusArray = inverterDevices.Select(b => b.ReadStatus()).NotNull().ToArray();
+
return new StatusRecord
{
InverterStatus = inverterDevice.ReadStatus(),
DcDcStatus = dcDcDevice.ReadStatus(),
- BatteryStatus = battery48TlDevice.ReadStatus(),
+#if BatteriesAllowed
+
+ BatteriesStatus = battery48TlStatusArray,
+ AvgBatteriesStatus = AvgBatteriesStatus.ReadBatteriesStatus(battery48TlStatusArray),
+#else
+ BatteriesStatus = null,
+ AvgBatteriesStatus = null,
+#endif
AcInToAcOutMeterStatus = acInToAcOutMeterDevice.ReadStatus(),
GridMeterStatus = gridMeterDevice.ReadStatus(),
SaliMaxRelayStatus = saliMaxRelaysDevice.ReadStatus(),
@@ -86,11 +118,12 @@ internal static class Program
};
}
-
- var startTime = UnixTime.Now;
+
+ var startTime = UnixTime.Now;
const Int32 delayTime = 10;
-
- ReleaseWriteTopology(startTime);
+
+
+ await UploadTopology(s3Config, Salimax.TopologyToLog(startTime), startTime);
DebugWriteTopology(startTime);
Console.WriteLine("press ctrl-C to stop");
@@ -104,19 +137,20 @@ internal static class Program
await Task.Delay(delayTime);
t = UnixTime.Now;
}
+
var status = ReadStatus();
- //var jsonLog = status.ToLog(t);
+#if BatteriesAllowed
- //await UploadTimeSeries(s3Config, jsonLog, t);
+ var jsonLog = status.ToLog(t);
+ await UploadTimeSeries(s3Config, jsonLog, t);
var controlRecord = Controller.Controller.SaliMaxControl(status);
Controller.Controller.WriteControlRecord(controlRecord, inverterDevice, dcDcDevice, saliMaxRelaysDevice);
- // JsonSerializer.Serialize(jsonLog, JsonOptions).WriteLine(ConsoleColor.DarkBlue);
-
- //ReleaseWriteLog(jsonLog, t);
+ //JsonSerializer.Serialize(jsonLog, JsonOptions).WriteLine(ConsoleColor.DarkBlue);
+#endif
PrintTopology(status);
-
- while (UnixTime.Now == t)
+
+ while (UnixTime.Now == t)
await Task.Delay(delayTime);
}
// ReSharper disable once FunctionNeverReturns
@@ -127,152 +161,191 @@ internal static class Program
{
const String chargingSeparator = ">>>>>>>>>>";
const String dischargingSeparator = "<<<<<<<<<";
- const Int32 height = 25;
+ const Int32 height = 25;
-
- var boxSize = chargingSeparator.Length / 2;
-
- var pwr = s.InverterStatus!.PowerAcL1 + s.InverterStatus.PowerAcL2 + s.InverterStatus.PowerAcL3;
- var pvPower = (s.AmptStatus!.Voltage1 * s.AmptStatus.Current1 + s.AmptStatus!.Voltage2 * s.AmptStatus.Current2).Round0();
- var loadPower = (s.GridMeterStatus!.ActivePowerL123 + pwr).Round3(); // it's a + because the pwr is inverted
+ var pwr = s.InverterStatus!.Ac.ActivePower;
+ var pvPower = (s.AmptStatus!.Devices[0].Dc.Voltage * s.AmptStatus.Devices[0].Dc.Current + s.AmptStatus!.Devices[1].Dc.Voltage * s.AmptStatus.Devices[1].Dc.Current).Round0(); // TODO using one Ampt
+ var loadPower = Utils.Round3((s.GridMeterStatus!.ActivePowerL123 + pwr)); // it's a + because the pwr is inverted
- var gridSeparator = s.GridMeterStatus!.ActivePowerL123 > 0 ? chargingSeparator : dischargingSeparator;
+ var gridSeparator = s.GridMeterStatus!.ActivePowerL123 > 0 ? chargingSeparator : dischargingSeparator;
var inverterSeparator = -pwr > 0 ? chargingSeparator : dischargingSeparator;
- var dcSeparator = -s.DcDcStatus!.DcPower > 0 ? chargingSeparator : dischargingSeparator;
- var batterySeparator = s.BatteryStatus!.Power > 0 ? chargingSeparator : dischargingSeparator;
-
-
- ////////////////// Grid //////////////////////
- var boxGrid = AsciiArt.CreateBox
+ var dcSeparator = -s.DcDcStatus!.Dc.Power > 0 ? chargingSeparator : dischargingSeparator;
+#if BatteriesAllowed
+ var battery1Separator = s.BatteriesStatus[0]!.Power > 0 ? chargingSeparator : dischargingSeparator;
+ var battery2Separator = s.BatteriesStatus[1]!.Power > 0 ? chargingSeparator : dischargingSeparator;
+#endif
+
+ ////////////////// Grid //////////////////////
+ var boxGrid = AsciiArt.CreateBox
(
"Grid",
- s.GridMeterStatus.VoltageL1N.V(),
- s.GridMeterStatus.VoltageL2N.V(),
- s.GridMeterStatus.VoltageL3N.V()
+ s.GridMeterStatus.Ac.L1.Voltage.V(),
+ s.GridMeterStatus.Ac.L2.Voltage.V(),
+ s.GridMeterStatus.Ac.L3.Voltage.V()
).AlignCenterVertical(height);
-
- //var gridBox = CreateRect(0, boxGrid).AlignBottom(height);
- var gridAcBusArrow = AsciiArt.CreateHorizontalArrow(s.GridMeterStatus!.ActivePowerL123.Round0(), gridSeparator).AlignCenterVertical(height);
-
-
+
+ var gridAcBusArrow = AsciiArt.CreateHorizontalArrow(s.GridMeterStatus!.ActivePowerL123.Round0(), gridSeparator)
+ .AlignCenterVertical(height);
+
+
////////////////// Ac Bus //////////////////////
- var boxAcBus = AsciiArt.CreateBox
+ var boxAcBus = AsciiArt.CreateBox
(
- "AC Bus",
- s.InverterStatus.GridVoltageL1.V(),
- s.InverterStatus.GridVoltageL2.V(),
- s.InverterStatus.GridVoltageL3.V()
+ "AC Bus",
+ s.InverterStatus.Ac.L1.Voltage.V(),
+ s.InverterStatus.Ac.L2.Voltage.V(),
+ s.InverterStatus.Ac.L3.Voltage.V()
);
-
+
var boxLoad = AsciiArt.CreateBox
(
"",
"LOAD",
""
);
-
- var loadRect = CreateRect(loadPower, boxAcBus, boxLoad).AlignBottom(height);
-
- var acBusInvertArrow = AsciiArt.CreateHorizontalArrow(-pwr.Round0(), inverterSeparator).AlignCenterVertical(height);
-
+
+ var loadRect = CreateRect(boxAcBus, boxLoad, loadPower).AlignBottom(height);
+
+ var acBusInvertArrow = AsciiArt.CreateHorizontalArrow(-pwr.Round0(), inverterSeparator)
+ .AlignCenterVertical(height);
+
//////////////////// Inverter /////////////////////////
var inverterBox = AsciiArt.CreateBox
- (
- "",
- "Inverter",
- ""
- ).AlignCenterVertical(height);
-
- var inverterArrow = AsciiArt.CreateHorizontalArrow(-pwr.Round0(), inverterSeparator).AlignCenterVertical(height);
-
-
- //////////////////// DC Bus /////////////////////////
- var dcBusBox = AsciiArt.CreateBox
- (
- "DC Bus",
- (s.InverterStatus.ActualDcLinkVoltageLowerHalfExt + s.InverterStatus.ActualDcLinkVoltageUpperHalfExt).V(),
- ""
- );
-
- var pvBox = AsciiArt.CreateBox
- (
- "",
- "MPPT",
- ""
- );
+ (
+ "",
+ "Inverter",
+ ""
+ ).AlignCenterVertical(height);
- var pvRect = CreateRect(pvPower, pvBox, dcBusBox).AlignTop(height);
-
- var dcBusArrow = AsciiArt.CreateHorizontalArrow(-s.DcDcStatus!.DcPower.Round0(), dcSeparator).AlignCenterVertical(height);
+ var inverterArrow = AsciiArt.CreateHorizontalArrow(-pwr.Round0(), inverterSeparator)
+ .AlignCenterVertical(height);
+
+
+ //////////////////// DC Bus /////////////////////////
+ var dcBusBox = AsciiArt.CreateBox
+ (
+ "DC Bus",
+ (s.InverterStatus.ActualDcLinkVoltageLowerHalfExt + s.InverterStatus.ActualDcLinkVoltageUpperHalfExt).V(),
+ ""
+ );
+
+ var pvBox = AsciiArt.CreateBox
+ (
+ "MPPT",
+ ((s.AmptStatus!.Devices[0].Dc.Voltage + s.AmptStatus!.Devices[1].Dc.Voltage) / 2).Round0().V(),
+ ""
+ );
+
+ var pvRect = CreateRect(pvBox, dcBusBox, pvPower).AlignTop(height);
+
+ var dcBusArrow = AsciiArt.CreateHorizontalArrow(-s.DcDcStatus!.Dc.Power, dcSeparator)
+ .AlignCenterVertical(height);
//////////////////// Dc/Dc /////////////////////////
var dcBox = AsciiArt.CreateBox
- (
- "",
- "Dc/Dc",
- ""
- ).AlignCenterVertical(height);
-
- var dcArrow = AsciiArt.CreateHorizontalArrow(s.BatteryStatus!.Power.Round0(), batterySeparator).AlignCenterVertical(height);
-
- //////////////////// Battery /////////////////////////
- var batteryBox = AsciiArt.CreateBox
- (
- "Battery",
- s.BatteryStatus!.Voltage.V(),
- ""
- ).AlignCenterVertical(height);
-
- var batteryDegree = AsciiArt.CreateTransitionPadLeft(s.BatteryStatus!.Soc.Percent(), s.BatteryStatus!.BatteryTemperature.Celsius()).AlignCenterVertical(height);
-
- // var loadLength = boxSize * 6;
- // var mpptLength = boxSize * 14;
- //
- // var mpptBox = AsciiArt.CreateVerticalPad(pvPower.W(),(Int16)mpptLength, true, "MPPT") + "\n";
- // var loadBox = AsciiArt.CreateVerticalPad(loadPower.W(), (Int16)loadLength, false, "Load");
+ (
+ "Dc/Dc",
+ s.DcDcStatus.BatteryVoltage.V(),
+ ""
+ ).AlignCenterVertical(height);
+#if BatteriesAllowed
+ var dcArrow1 = AsciiArt.CreateHorizontalArrow(s.BatteriesStatus[0]!.Power.Round0(), battery1Separator);
+ var dcArrow2 = AsciiArt.CreateHorizontalArrow(s.BatteriesStatus[1]!.Power.Round0(), battery2Separator);
+#else
+ var dcArrow1 ="";
+ var dcArrow2 = "";
+ var dcArrowRect = CreateRect(dcArrow1, dcArrow2).AlignCenterVertical(height);
+#endif
- var topology = boxGrid.SideBySideWith(gridAcBusArrow,"")
- .SideBySideWith(loadRect,"")
- .SideBySideWith(acBusInvertArrow,"")
- .SideBySideWith(inverterBox,"")
- .SideBySideWith(inverterArrow,"")
- .SideBySideWith(pvRect,"")
- .SideBySideWith(dcBusArrow,"")
- .SideBySideWith(dcBox,"")
- .SideBySideWith(dcArrow,"")
- .SideBySideWith(batteryBox,"")
- .SideBySideWith(batteryDegree, "") + "\n";
-
- // var topology = mpptBox + boxSide11 + loadBox;
+#if BatteriesAllowed
+ //////////////////// Batteries /////////////////////////
+ var battery1Box = AsciiArt.CreateBox
+ (
+ "Battery 1",
+ s.BatteriesStatus[0].Voltage.V(),
+ s.BatteriesStatus[0].Soc.Percent(),
+ s.BatteriesStatus[0].Temperature.Celsius()
+ );
+
+ var battery2Box = AsciiArt.CreateBox
+ (
+ "Battery 2",
+ s.BatteriesStatus[1].Voltage.V(),
+ s.BatteriesStatus[1].Soc.Percent(),
+ s.BatteriesStatus[1].Temperature.Celsius()
+ );
+
+ var batteryRect = CreateRect(battery1Box, battery2Box).AlignCenterVertical(height);
+
+ var avgBatteryBox = AsciiArt.CreateBox
+ (
+ "Batteries",
+ s.AvgBatteriesStatus!.Voltage.V(),
+ s.AvgBatteriesStatus.Soc.Percent(),
+ s.AvgBatteriesStatus.Temperature.Celsius()
+ ).AlignCenterVertical(height);
+
+
+ var topology = boxGrid.SideBySideWith(gridAcBusArrow, "")
+ .SideBySideWith(loadRect, "")
+ .SideBySideWith(acBusInvertArrow, "")
+ .SideBySideWith(inverterBox, "")
+ .SideBySideWith(inverterArrow, "")
+ .SideBySideWith(pvRect, "")
+ .SideBySideWith(dcBusArrow, "")
+ .SideBySideWith(dcBox, "")
+ .SideBySideWith(dcArrowRect, "")
+ .SideBySideWith(batteryRect, "")
+ .SideBySideWith(avgBatteryBox, "")+ "\n";
+#else
+ var topology = boxGrid.SideBySideWith(gridAcBusArrow, "")
+ .SideBySideWith(loadRect, "")
+ .SideBySideWith(acBusInvertArrow, "")
+ .SideBySideWith(inverterBox, "")
+ .SideBySideWith(inverterArrow, "")
+ .SideBySideWith(pvRect, "")
+ .SideBySideWith(dcBusArrow, "")
+ .SideBySideWith(dcBox, "")+ "\n";
+#endif
Console.WriteLine(topology);
- // Console.WriteLine(loadRect);
- // Console.WriteLine(pvRect);
}
- private static String CreateRect(Decimal loadPower, String boxAcBus, String boxLoad = "")
+ private static String CreateRect(String boxTop, String boxBottom, Decimal power)
{
- var loadAcBusArrow = AsciiArt.CreateVerticalArrow(loadPower);
- var boxes = new[] { boxAcBus, loadAcBusArrow, boxLoad };
+ var powerArrow = AsciiArt.CreateVerticalArrow(power);
+ var boxes = new[] { boxTop, powerArrow, boxBottom };
var maxWidth = boxes.Max(l => l.Width());
var rect = boxes.Select(l => l.AlignCenterHorizontal(maxWidth)).JoinLines();
return rect;
}
+ private static String CreateRect(String boxTop, String boxBottom)
+ {
+ var boxes = new[] { boxTop, boxBottom };
+ var maxWidth = boxes.Max(l => l.Width());
+
+ var rect = boxes.Select(l => l.AlignCenterHorizontal(maxWidth)).JoinLines();
+ return rect;
+ }
+
+ // to delete not used anymore
[Conditional("RELEASE")]
private static void ReleaseWriteLog(JsonObject jsonLog, UnixTime timestamp)
{
- WriteToFile(jsonLog, "/home/debian/DataSaliMax/" + timestamp);
+ // WriteToFile(jsonLog, "/home/debian/DataSaliMax/" + timestamp); // this is was for beaglebone TODO
}
- [Conditional("RELEASE")]
- private static void ReleaseWriteTopology(UnixTime timestamp)
+ // [Conditional("RELEASE")]
+ private static JsonObject ReleaseWriteTopology(UnixTime timestamp)
{
var topologyJson = Salimax.TopologyToLog(timestamp);
- WriteToFile(topologyJson, "/home/debian/DataSaliMax/topology" + timestamp);
+
+ // WriteToFile(topologyJson, "/home/debian/DataSaliMax/topology" + timestamp); // this is was for beaglebone
+ return topologyJson;
}
[Conditional("DEBUG")]
@@ -318,4 +391,19 @@ internal static class Program
Console.WriteLine(error);
}
}
+
+ private static async Task UploadTopology(S3Config config, JsonObject json, UnixTime unixTime)
+ {
+ var payload = JsonSerializer.Serialize(json, JsonOptions);
+ var s3Path = "topology" + unixTime.Ticks + ".json";
+ var request = config.CreatePutRequest(s3Path);
+ var response = await request.PutAsync(new StringContent(payload));
+
+ if (response.StatusCode != 200)
+ {
+ Console.WriteLine("ERROR: PUT");
+ var error = response.GetStringAsync();
+ Console.WriteLine(error);
+ }
+ }
}
\ No newline at end of file
diff --git a/csharp/app/SaliMax/src/SaliMaxRelays/SaliMaxRelaysStatus.cs b/csharp/app/SaliMax/src/SaliMaxRelays/SaliMaxRelaysStatus.cs
index 26b72c005..64c08b992 100644
--- a/csharp/app/SaliMax/src/SaliMaxRelays/SaliMaxRelaysStatus.cs
+++ b/csharp/app/SaliMax/src/SaliMaxRelays/SaliMaxRelaysStatus.cs
@@ -2,9 +2,6 @@ namespace InnovEnergy.SaliMax.SaliMaxRelays;
public record SaliMaxRelayStatus
{
- internal const UInt16 DigitalInputsStartRegister = 1;
- internal const UInt16 NbDigitalInputs = 6;
-
public RelayState K1 { get; init; } = RelayState.Closed; // Address on Adam(0X) 00002
public RelayState K2 { get; init; } = RelayState.Closed; // Address on Adam(0X) 00003
public RelayState K3 { get; init; } = RelayState.Closed; // Address on Adam(0X) 00004
diff --git a/csharp/app/SaliMax/src/SystemConfig/Config.cs b/csharp/app/SaliMax/src/SystemConfig/Config.cs
index aaa8b3a86..c11f7d6f7 100644
--- a/csharp/app/SaliMax/src/SystemConfig/Config.cs
+++ b/csharp/app/SaliMax/src/SystemConfig/Config.cs
@@ -2,5 +2,5 @@ namespace InnovEnergy.SaliMax.SystemConfig;
public static class Config
{
- public const String LogSalimaxLog = "/home/debian/Salimax.log";
+ public const String LogSalimaxLog = "/home/ie-entwicklung/Salimax.log"; // todo remove ie-entwicklung
}
\ No newline at end of file
diff --git a/csharp/app/SaliMax/src/SystemConfig/Defaults.cs b/csharp/app/SaliMax/src/SystemConfig/Defaults.cs
index c45e9ae49..6b11b6ad1 100644
--- a/csharp/app/SaliMax/src/SystemConfig/Defaults.cs
+++ b/csharp/app/SaliMax/src/SystemConfig/Defaults.cs
@@ -13,7 +13,7 @@ public static class Defaults
Subnet = default, //= 0x FFFFFF00;
Gateway = default, //= 0x C0A80102;
ResetParamToDefault = false, // Coil
- CommunicationTimeout = default,
+ CommunicationTimeout = TimeSpan.FromSeconds(10),
FactoryResetParameters = false,
ConnectedSystemConfig = Lib.Devices.Trumpf.TruConvert.SystemConfig.AcDcAndDcDc,
UpdateSwTrigger = 0,
@@ -25,7 +25,7 @@ public static class Defaults
// IlBuildnumber = 0,
PowerStageEnable = true,
SetValueConfig = SymmetricAcOperationMode.Symmetric, // Asymmetric = 0, // this is can not be seen in UI
- ResetsAlarmAndWarning = false,
+ ResetsAlarmAndWarning = true,
PreChargeDcLinkConfig = PreChargeDcLinkConfig.Internal, // 1 = internal
PowerFactorConvention = PowerFactorConvention.Producer, // 0 = producer
SlaveAddress = 1,
@@ -66,9 +66,9 @@ public static class Defaults
GridFormingMode = 0, // 0 = not grid-forming (grid-tied) ,1 = grid-forming TODO enum
//remove DC stuff from AC
- DcLinkRefVoltage = 850,
- DcLinkMinVoltage = 830,
- DcLinkMaxVoltage = 870,
+ DcLinkRefVoltage = 800,
+ DcLinkMinVoltage = 780,
+ DcLinkMaxVoltage = 820,
DcVoltageRefUs = 900,
DcMinVoltageUs = 880,
DcMaxVoltageUs = 920,
@@ -88,7 +88,7 @@ public static class Defaults
Subnet = default,
Gateway = default,
ResetParamToDefault = false ,
- TimeoutForCommunication = default ,
+ TimeoutForCommunication = TimeSpan.FromSeconds(10) ,
RestartFlag = false ,
ConnectedSystemConfig = Lib.Devices.Trumpf.TruConvert.SystemConfig.DcDcOnly,
UpdateSwTrigger = 0,
@@ -98,7 +98,7 @@ public static class Defaults
SerialNumberDcDc = 0,
MaterialNumberDcDc = 0,
PowerStageEnable = true,
- ResetsAlarmAndWarning = false,
+ ResetsAlarmAndWarning = false,
SlaveAddress = 1,
SubSlaveAddress = 0,
ModbusSlaveId = false,
@@ -112,7 +112,7 @@ public static class Defaults
BatteryCurrentSet = 0,
DynamicCurrentPerMillisecond = 2,
DcLinkControlMode = 1,
- ReferenceVoltage = 850,
+ ReferenceVoltage = 800,
UpperVoltageWindow = 40,
LowerVoltageWindow = 40,
VoltageDeadBand = 0,
diff --git a/csharp/lib/Devices/AMPT/AmptCommunicationUnit.cs b/csharp/lib/Devices/AMPT/AmptCommunicationUnit.cs
index 5bc17c343..239502762 100644
--- a/csharp/lib/Devices/AMPT/AmptCommunicationUnit.cs
+++ b/csharp/lib/Devices/AMPT/AmptCommunicationUnit.cs
@@ -1,6 +1,7 @@
using DecimalMath;
using InnovEnergy.Lib.Protocols.Modbus.Clients;
using InnovEnergy.Lib.Protocols.Modbus.Connections;
+using InnovEnergy.Lib.StatusApi.Connections;
namespace InnovEnergy.Lib.Devices.Ampt;
@@ -48,25 +49,22 @@ public class AmptCommunicationUnit
.ToList();
var amptSt = new AmptStatus
- {
- Sid = r.GetUInt32(1),
- IdSunSpec = r.GetUInt16(3),
- Manufacturer = r.GetString(5, 16),
- Model = r.GetString(21, 16),
- Version = r.GetString(45, 8),
- SerialNumber = r.GetString(53, 16),
- DeviceAddress = r.GetInt16(69),
- IdVendor = r.GetUInt16(71),
- Devices = devices,
- Current1 = r.GetInt16(90) * currentFactor,
- Current2 = r.GetInt16(106) * currentFactor,
- Voltage1 = r.GetUInt32(91) * voltageFactor,
- Voltage2 = r.GetUInt32(107) * voltageFactor,
-
- //AvgVolatge = ReadDevicesVoltage(nbrOfDevices),
- //AvgCurrent = ReadDevicesCurrent(nbrOfDevices)
+ (
+ Sid : r.GetUInt32(1),
+ IdSunSpec : r.GetUInt16(3),
+ Manufacturer : r.GetString(5, 16),
+ Model : r.GetString(21, 16),
+ Version : r.GetString(45, 8),
+ SerialNumber : r.GetString(53, 16),
+ DeviceAddress : r.GetInt16(69),
+ IdVendor : r.GetUInt16(71),
+ Devices : devices
+ // devices.d Current1 = r.GetInt16(90) * currentFactor,
+ // Current2 = r.GetInt16(106) * currentFactor,
+ // Voltage1 = r.GetUInt32(91) * voltageFactor,
+ // Voltage2 = r.GetUInt32(107) * voltageFactor
- };
+ );
return amptSt;
@@ -104,26 +102,30 @@ public class AmptCommunicationUnit
var b = (UInt16)(FirstDeviceOffset + deviceNumber * RegistersPerDevice); // base address
return new AmptDeviceStatus
- {
- DeviceId = r.GetInt16 (b) ,
- Timestamp = r.GetUInt32((UInt16)(b + 3)),
- Current = r.GetUInt16((UInt16)(b + 5)) * currentFactor,
- Voltage = r.GetUInt32((UInt16)(b + 6)) * voltageFactor,
- ProductionToday = r.GetUInt32((UInt16)(b + 12))* energyFactor,
- Strings = new AmptStringStatus[]
+ (
+ Dc : new DcConnection
+ (
+ Voltage:r.GetUInt32((UInt16)(b + 6)) * voltageFactor,
+ Current:r.GetUInt16((UInt16)(b + 5)) * currentFactor
+ ),
+ DeviceId : r.GetInt16 (b) ,
+ Timestamp : r.GetUInt32((UInt16)(b + 3)),
+ ProductionToday : r.GetUInt32((UInt16)(b + 12))* energyFactor,
+
+ Strings : new []
{
- new()
- {
- Voltage = r.GetUInt32((UInt16)(b + 8)) * voltageFactor,
- Current = r.GetUInt16((UInt16)(b + 14)) * currentFactor,
- },
- new()
- {
- Voltage = r.GetUInt32((UInt16)(b + 9)) * voltageFactor,
- Current = r.GetUInt16((UInt16)(b + 15)) * currentFactor,
- }
+ new DcConnection
+ (
+ Voltage : r.GetUInt32((UInt16)(b + 8)) * voltageFactor,
+ Current : r.GetUInt16((UInt16)(b + 14)) * currentFactor
+ ),
+ new DcConnection
+ (
+ Voltage : r.GetUInt32((UInt16)(b + 9)) * voltageFactor,
+ Current : r.GetUInt16((UInt16)(b + 15)) * currentFactor
+ )
}
- };
+ );
}
}
}
\ No newline at end of file
diff --git a/csharp/lib/Devices/AMPT/AmptDeviceStatus.cs b/csharp/lib/Devices/AMPT/AmptDeviceStatus.cs
index faf77054a..00d9e352f 100644
--- a/csharp/lib/Devices/AMPT/AmptDeviceStatus.cs
+++ b/csharp/lib/Devices/AMPT/AmptDeviceStatus.cs
@@ -1,14 +1,15 @@
+using InnovEnergy.Lib.StatusApi.Connections;
+using InnovEnergy.Lib.StatusApi.Devices;
+
namespace InnovEnergy.Lib.Devices.Ampt;
public record AmptDeviceStatus
-{
- internal const UInt16 NbrOfStrings = 2;
- public Int16 DeviceId { get; init; } // The string number
- public UInt32 Timestamp { get; init; } // The UTC timestamp of the measurements
-
- public Decimal Current { get; init; } // String output current in mA
- public Decimal Voltage { get; init; } // String output voltage in mV
-
- public Decimal ProductionToday { get; init; } // converted to kW in AmptCU class
- public IReadOnlyList Strings { get; init; } = null!;
-}
\ No newline at end of file
+(
+ DcConnection Dc,
+ // UInt16 NbrOfStrings,
+ Int16 DeviceId, // The string number
+ UInt32 Timestamp, // The UTC timestamp of the measurements
+ Decimal ProductionToday, // converted to kW in AmptCU class
+ IReadOnlyList Strings
+): Mppt(Dc, Strings)
+{}
\ No newline at end of file
diff --git a/csharp/lib/Devices/AMPT/AmptStatus.cs b/csharp/lib/Devices/AMPT/AmptStatus.cs
index 792a7c5b2..48ce01d2f 100644
--- a/csharp/lib/Devices/AMPT/AmptStatus.cs
+++ b/csharp/lib/Devices/AMPT/AmptStatus.cs
@@ -1,25 +1,27 @@
+using InnovEnergy.Lib.StatusApi.Connections;
+using InnovEnergy.Lib.StatusApi.Devices;
+
namespace InnovEnergy.Lib.Devices.Ampt;
public record AmptStatus
+(
+ UInt32 Sid, // A well-known value 0x53756e53, uniquely identifies this as a SunSpec Modbus Map
+ UInt16 IdSunSpec, // A well-known value 1, uniquely identifies this as a SunSpec Common Model
+ // UInt16 L, // Well-known # of 16-bit registers to follow : 66
+ String? Manufacturer, // A well-known value registered with SunSpec for compliance: "Ampt"
+ String? Model, // Manufacturer specific value "Communication Unit"
+ String? Version, // Software Version
+ String? SerialNumber, // Manufacturer specific value
+ Int16 DeviceAddress, // Modbus Device ID
+ UInt16 IdVendor, // Ampt SunSpec Vendor Code 64050
+ // Decimal Current1,
+ // Decimal Current2,
+ // Decimal Voltage1,
+ // Decimal Voltage2,
+ IReadOnlyList Devices
+ //internal const UInt16 StartRegister = 1;
+ //internal const UInt16 TotalNbOfRegister = 116;
+)
{
- internal const UInt16 StartRegister = 1;
- internal const UInt16 TotalNbOfRegister = 116;
-
- public 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 UInt16 L { get; init; } // Well-known # of 16-bit registers to follow : 66
- public String? Manufacturer { get; init; } // A well-known value registered with SunSpec for compliance: "Ampt"
- public String? Model { get; init; } // Manufacturer specific value "Communication Unit"
- public String? Version { get; init; } // Software Version
- public String? SerialNumber { get; init; } // Manufacturer specific value
- public Int16 DeviceAddress { get; init; } // Modbus Device ID
- public UInt16 IdVendor { get; init; } // Ampt SunSpec Vendor Code 64050
- public Decimal AvgVolatge { get; init; }
- public Decimal AvgCurrent { get; init; }
- public Decimal Current1 { get; init; }
- public Decimal Current2 { get; init; }
- public Decimal Voltage1 { get; init; }
- public Decimal Voltage2 { get; init; }
- public IReadOnlyList Devices { get; init; } = null!;
}
\ No newline at end of file
diff --git a/csharp/lib/Devices/Battery48TL/Battery48TL.csproj b/csharp/lib/Devices/Battery48TL/Battery48TL.csproj
index 17cea97fb..51feacfe1 100644
--- a/csharp/lib/Devices/Battery48TL/Battery48TL.csproj
+++ b/csharp/lib/Devices/Battery48TL/Battery48TL.csproj
@@ -9,6 +9,7 @@
+
diff --git a/csharp/lib/Devices/Battery48TL/Battery48TLDevice.cs b/csharp/lib/Devices/Battery48TL/Battery48TLDevice.cs
index 15bf1a882..979eafaf7 100644
--- a/csharp/lib/Devices/Battery48TL/Battery48TLDevice.cs
+++ b/csharp/lib/Devices/Battery48TL/Battery48TLDevice.cs
@@ -1,5 +1,7 @@
using InnovEnergy.Lib.Protocols.Modbus.Clients;
using InnovEnergy.Lib.Protocols.Modbus.Connections;
+using InnovEnergy.Lib.Protocols.Modbus.Conversions;
+using InnovEnergy.Lib.StatusApi.Connections;
namespace InnovEnergy.Lib.Devices.Battery48TL;
@@ -33,6 +35,7 @@ public class Battery48TlDevice
{
if (Modbus is null) // TODO : remove fake
{
+ Console.WriteLine("Battery is null");
return null;
}
@@ -41,13 +44,101 @@ public class Battery48TlDevice
try
{
var registers = Modbus.ReadInputRegisters(Constants.BaseAddress, Constants.NoOfRegisters);
- return new Battery48TLStatus(registers);
+ return TryReadStatus(registers);
}
catch (Exception e)
{
- Console.WriteLine(e.Message);
+ Console.WriteLine(e.Message + " Battery ");
Modbus.CloseConnection();
return null;
}
}
+
+ private Battery48TLStatus? TryReadStatus(ModbusRegisters data)
+ {
+ var soc = data.ParseDecimal(register: 1054, scaleFactor: 0.1m);
+ var eocReached = data.ParseEocReached();
+
+ var warnings = new List();
+
+ if (data.ParseBool(1006, 1)) warnings.Add("TaM1: BMS temperature high");
+ if (data.ParseBool(1006, 4)) warnings.Add("TbM1: Battery temperature high");
+ if (data.ParseBool(1006, 6)) warnings.Add("VBm1: Bus voltage low");
+ if (data.ParseBool(1006, 8)) warnings.Add("VBM1: Bus voltage high");
+ if (data.ParseBool(1006, 10)) warnings.Add("IDM1: Discharge current high");
+ if (data.ParseBool(1006, 24)) warnings.Add("vsM1: String voltage high");
+ if (data.ParseBool(1006, 26)) warnings.Add("iCM1: Charge current high");
+ if (data.ParseBool(1006, 28)) warnings.Add("iDM1: Discharge current high");
+ if (data.ParseBool(1006, 30)) warnings.Add("MID1: String voltages unbalanced");
+ if (data.ParseBool(1006, 32)) warnings.Add("BLPW: Not enough charging power on bus");
+ if (data.ParseBool(1006, 35)) warnings.Add("Ah_W: String SOC low");
+ if (data.ParseBool(1006, 38)) warnings.Add("MPMM: Midpoint wiring problem");
+ if (data.ParseBool(1006, 39)) warnings.Add("TCMM:");
+ if (data.ParseBool(1006, 40)) warnings.Add("TCdi: Temperature difference between strings high");
+ if (data.ParseBool(1006, 41)) warnings.Add("WMTO:");
+ if (data.ParseBool(1006, 44)) warnings.Add("bit44:");
+ if (data.ParseBool(1006, 46)) warnings.Add("CELL1:");
+
+ var alarms = new List();
+
+ if (data.ParseBool(1010, 0)) alarms.Add("Tam : BMS temperature too low");
+ if (data.ParseBool(1010, 2)) alarms.Add("TaM2 : BMS temperature too high");
+ if (data.ParseBool(1010, 3)) alarms.Add("Tbm : Battery temperature too low");
+ if (data.ParseBool(1010, 5)) alarms.Add("TbM2 : Battery temperature too high");
+ if (data.ParseBool(1010, 7)) alarms.Add("VBm2 : Bus voltage too low");
+ if (data.ParseBool(1010, 9)) alarms.Add("VBM2 : Bus voltage too high");
+ if (data.ParseBool(1010, 11)) alarms.Add("IDM2 : Discharge current too high");
+ if (data.ParseBool(1010, 12)) alarms.Add("ISOB : Electrical insulation failure");
+ if (data.ParseBool(1010, 13)) alarms.Add("MSWE : Main switch failure");
+ if (data.ParseBool(1010, 14)) alarms.Add("FUSE : Main fuse blown");
+ if (data.ParseBool(1010, 15)) alarms.Add("HTRE : Battery failed to warm up");
+ if (data.ParseBool(1010, 16)) alarms.Add("TCPE : Temperature sensor failure");
+ if (data.ParseBool(1010, 17)) alarms.Add("STRE :");
+ if (data.ParseBool(1010, 18)) alarms.Add("CME : Current sensor failure");
+ if (data.ParseBool(1010, 19)) alarms.Add("HWFL : BMS hardware failure");
+ if (data.ParseBool(1010, 20)) alarms.Add("HWEM : Hardware protection tripped");
+ if (data.ParseBool(1010, 21)) alarms.Add("ThM : Heatsink temperature too high");
+ if (data.ParseBool(1010, 22)) alarms.Add("vsm1 : String voltage too low");
+ if (data.ParseBool(1010, 23)) alarms.Add("vsm2 : Low string voltage failure");
+ if (data.ParseBool(1010, 25)) alarms.Add("vsM2 : String voltage too high");
+ if (data.ParseBool(1010, 27)) alarms.Add("iCM2 : Charge current too high");
+ if (data.ParseBool(1010, 29)) alarms.Add("iDM2 : Discharge current too high");
+ if (data.ParseBool(1010, 31)) alarms.Add("MID2 : String voltage unbalance too high");
+ if (data.ParseBool(1010, 33)) alarms.Add("CCBF : Internal charger hardware failure");
+ if (data.ParseBool(1010, 34)) alarms.Add("AhFL :");
+ if (data.ParseBool(1010, 36)) alarms.Add("TbCM :");
+ if (data.ParseBool(1010, 37)) alarms.Add("BRNF :");
+ if (data.ParseBool(1010, 42)) alarms.Add("HTFS : If Heaters Fuse Blown");
+ if (data.ParseBool(1010, 43)) alarms.Add("DATA : Parameters out of range");
+ if (data.ParseBool(1010, 45)) alarms.Add("CELL2:");
+
+
+return new Battery48TLStatus(
+ Dc: new DcConnection
+ (
+ Voltage : data.ReadVoltage(),
+ Current : data.ReadCurrent()),
+
+ Soc : !eocReached && soc >= 100m ? 99.9m : soc,
+ Temperature : data.ParseDecimal(register: 1004, scaleFactor: 0.1m, offset: -400),
+ BusVoltage : data.ParseDecimal(register: 1002, scaleFactor: 0.01m),
+ GreenLed : data.ParseLedState(register: 1005, led: LedColor.Green),
+ AmberLed : data.ParseLedState(register: 1006, led: LedColor.Amber),
+ BlueLed : data.ParseLedState(register: 1005, led: LedColor.Blue),
+ RedLed : data.ParseLedState(register: 1005, led: LedColor.Red),
+ Warnings : warnings,
+ Alarms : alarms,
+ MainSwitchClosed : data.ParseBool(baseRegister: 1014, bit: 0),
+ AlarmOutActive : data.ParseBool(baseRegister: 1014, bit: 1),
+ InternalFanActive : data.ParseBool(baseRegister: 1014, bit: 2),
+ VoltMeasurementAllowed: data.ParseBool(baseRegister: 1014, bit: 3),
+ AuxRelay : data.ParseBool(baseRegister: 1014, bit: 4),
+ RemoteState : data.ParseBool(baseRegister: 1014, bit: 5),
+ HeaterOn : data.ParseBool(baseRegister: 1014, bit: 6),
+ EocReached : eocReached,
+ BatteryCold : data.ParseBatteryCold(),
+ MaxChargingPower : data.CalcMaxChargePower(),
+ MaxDischargingPower : data.CalcMaxDischargePower()
+ );
+ }
}
\ No newline at end of file
diff --git a/csharp/lib/Devices/Battery48TL/Battery48TLStatusRecord.cs b/csharp/lib/Devices/Battery48TL/Battery48TLStatusRecord.cs
index 38ae8affa..0871f0645 100644
--- a/csharp/lib/Devices/Battery48TL/Battery48TLStatusRecord.cs
+++ b/csharp/lib/Devices/Battery48TL/Battery48TLStatusRecord.cs
@@ -1,118 +1,39 @@
using System.Diagnostics.CodeAnalysis;
using InnovEnergy.Lib.Protocols.Modbus.Conversions;
+using InnovEnergy.Lib.StatusApi.Connections;
+using InnovEnergy.Lib.StatusApi.Devices;
namespace InnovEnergy.Lib.Devices.Battery48TL;
[SuppressMessage("ReSharper", "InconsistentNaming")]
-public class Battery48TLStatus
+public record Battery48TLStatus
+(
+ DcConnection Dc,
+ Decimal Soc,
+ Decimal Temperature,
+ //Decimal Current,
+ //Decimal Voltage,
+ Decimal BusVoltage,
+ LedState GreenLed,
+ LedState AmberLed,
+ LedState BlueLed,
+ LedState RedLed,
+ IReadOnlyList Warnings,
+ IReadOnlyList Alarms,
+ Boolean MainSwitchClosed,
+ Boolean AlarmOutActive,
+ Boolean InternalFanActive,
+ Boolean VoltMeasurementAllowed,
+ Boolean AuxRelay,
+ Boolean RemoteState,
+ Boolean HeaterOn,
+ Boolean EocReached,
+ Boolean BatteryCold,
+ Decimal MaxChargingPower,
+ Decimal MaxDischargingPower
+)
+: Battery(Dc, Soc, Temperature)
{
- public Decimal Soc { get; }
- public Decimal Current { get; }
- public Decimal Voltage { get; }
- public Decimal Power => Current * Voltage; // TODO do we have to invert the sign here?
- public Decimal BusVoltage { get; }
- public Decimal BatteryTemperature { get; }
- public LedState GreenLed { get; }
- public LedState AmberLed { get; }
- public LedState BlueLed { get; }
- public LedState RedLed { get; }
- public IReadOnlyList Warnings { get; }
- public IReadOnlyList Alarms { get; }
- public Boolean MainSwitchClosed { get; }
- public Boolean AlarmOutActive { get; }
- public Boolean InternalFanActive { get; }
- public Boolean VoltMeasurementAllowed { get; }
- public Boolean AuxRelay { get; }
- public Boolean RemoteState { get; }
- public Boolean HeaterOn { get; }
- public Boolean EocReached { get; }
- public Boolean BatteryCold { get; }
- public Decimal MaxChargingPower { get; }
- public Decimal MaxDischargingPower { get; }
-
-
- public Battery48TLStatus(ModbusRegisters data)
- {
-
- var soc = data.ParseDecimal(register: 1054, scaleFactor: 0.1m);
- var eocReached = data.ParseEocReached();
-
- var warnings = new List();
-
- if (data.ParseBool(1006, 1)) warnings.Add("TaM1: BMS temperature high");
- if (data.ParseBool(1006, 4)) warnings.Add("TbM1: Battery temperature high");
- if (data.ParseBool(1006, 6)) warnings.Add("VBm1: Bus voltage low");
- if (data.ParseBool(1006, 8)) warnings.Add("VBM1: Bus voltage high");
- if (data.ParseBool(1006, 10)) warnings.Add("IDM1: Discharge current high");
- if (data.ParseBool(1006, 24)) warnings.Add("vsM1: String voltage high");
- if (data.ParseBool(1006, 26)) warnings.Add("iCM1: Charge current high");
- if (data.ParseBool(1006, 28)) warnings.Add("iDM1: Discharge current high");
- if (data.ParseBool(1006, 30)) warnings.Add("MID1: String voltages unbalanced");
- if (data.ParseBool(1006, 32)) warnings.Add("BLPW: Not enough charging power on bus");
- if (data.ParseBool(1006, 35)) warnings.Add("Ah_W: String SOC low");
- if (data.ParseBool(1006, 38)) warnings.Add("MPMM: Midpoint wiring problem");
- if (data.ParseBool(1006, 39)) warnings.Add("TCMM:");
- if (data.ParseBool(1006, 40)) warnings.Add("TCdi: Temperature difference between strings high");
- if (data.ParseBool(1006, 41)) warnings.Add("WMTO:");
- if (data.ParseBool(1006, 44)) warnings.Add("bit44:");
- if (data.ParseBool(1006, 46)) warnings.Add("CELL1:");
-
- var alarms = new List();
-
- if (data.ParseBool(1010, 0)) alarms.Add("Tam : BMS temperature too low");
- if (data.ParseBool(1010, 2)) alarms.Add("TaM2 : BMS temperature too high");
- if (data.ParseBool(1010, 3)) alarms.Add("Tbm : Battery temperature too low");
- if (data.ParseBool(1010, 5)) alarms.Add("TbM2 : Battery temperature too high");
- if (data.ParseBool(1010, 7)) alarms.Add("VBm2 : Bus voltage too low");
- if (data.ParseBool(1010, 9)) alarms.Add("VBM2 : Bus voltage too high");
- if (data.ParseBool(1010, 11)) alarms.Add("IDM2 : Discharge current too high");
- if (data.ParseBool(1010, 12)) alarms.Add("ISOB : Electrical insulation failure");
- if (data.ParseBool(1010, 13)) alarms.Add("MSWE : Main switch failure");
- if (data.ParseBool(1010, 14)) alarms.Add("FUSE : Main fuse blown");
- if (data.ParseBool(1010, 15)) alarms.Add("HTRE : Battery failed to warm up");
- if (data.ParseBool(1010, 16)) alarms.Add("TCPE : Temperature sensor failure");
- if (data.ParseBool(1010, 17)) alarms.Add("STRE :");
- if (data.ParseBool(1010, 18)) alarms.Add("CME : Current sensor failure");
- if (data.ParseBool(1010, 19)) alarms.Add("HWFL : BMS hardware failure");
- if (data.ParseBool(1010, 20)) alarms.Add("HWEM : Hardware protection tripped");
- if (data.ParseBool(1010, 21)) alarms.Add("ThM : Heatsink temperature too high");
- if (data.ParseBool(1010, 22)) alarms.Add("vsm1 : String voltage too low");
- if (data.ParseBool(1010, 23)) alarms.Add("vsm2 : Low string voltage failure");
- if (data.ParseBool(1010, 25)) alarms.Add("vsM2 : String voltage too high");
- if (data.ParseBool(1010, 27)) alarms.Add("iCM2 : Charge current too high");
- if (data.ParseBool(1010, 29)) alarms.Add("iDM2 : Discharge current too high");
- if (data.ParseBool(1010, 31)) alarms.Add("MID2 : String voltage unbalance too high");
- if (data.ParseBool(1010, 33)) alarms.Add("CCBF : Internal charger hardware failure");
- if (data.ParseBool(1010, 34)) alarms.Add("AhFL :");
- if (data.ParseBool(1010, 36)) alarms.Add("TbCM :");
- if (data.ParseBool(1010, 37)) alarms.Add("BRNF :");
- if (data.ParseBool(1010, 42)) alarms.Add("HTFS : If Heaters Fuse Blown");
- if (data.ParseBool(1010, 43)) alarms.Add("DATA : Parameters out of range");
- if (data.ParseBool(1010, 45)) alarms.Add("CELL2:");
-
- Voltage = data.ReadVoltage();
- Current = data.ReadCurrent();
- Soc = !eocReached && soc >= 100m ? 99.9m : soc;
- BusVoltage = data.ParseDecimal(register: 1002, scaleFactor: 0.01m);
- BatteryTemperature = data.ParseDecimal(register: 1004, scaleFactor: 0.1m, offset: -400);
- GreenLed = data.ParseLedState(register: 1005, led: LedColor.Green);
- AmberLed = data.ParseLedState(register: 1006, led: LedColor.Amber);
- BlueLed = data.ParseLedState(register: 1005, led: LedColor.Blue);
- RedLed = data.ParseLedState(register: 1005, led: LedColor.Red);
- Warnings = warnings;
- Alarms = alarms;
- MainSwitchClosed = data.ParseBool(baseRegister: 1014, bit: 0);
- AlarmOutActive = data.ParseBool(baseRegister: 1014, bit: 1);
- InternalFanActive = data.ParseBool(baseRegister: 1014, bit: 2);
- VoltMeasurementAllowed = data.ParseBool(baseRegister: 1014, bit: 3);
- AuxRelay = data.ParseBool(baseRegister: 1014, bit: 4);
- RemoteState = data.ParseBool(baseRegister: 1014, bit: 5);
- HeaterOn = data.ParseBool(baseRegister: 1014, bit: 6);
- EocReached = eocReached;
- BatteryCold = data.ParseBatteryCold();
- MaxChargingPower = data.CalcMaxChargePower();
- MaxDischargingPower = data.CalcMaxDischargePower();
- }
}
diff --git a/csharp/lib/Devices/Battery48TL/BatteryDataParser.cs b/csharp/lib/Devices/Battery48TL/BatteryDataParser.cs
index 50e4b4ae1..916c8989c 100644
--- a/csharp/lib/Devices/Battery48TL/BatteryDataParser.cs
+++ b/csharp/lib/Devices/Battery48TL/BatteryDataParser.cs
@@ -110,6 +110,22 @@ public static class BatteryDataParser
return pLimit;
}
+
+
+ private static Decimal CalcPowerLimitImposedByTempLimit(Decimal t, Decimal maxAllowedTemp, Decimal power , Decimal setpoint)
+ {
+ // const Int32 holdZone = 300;
+ // const Int32 maxAllowedTemp = 315;
+
+ var kp = 0.05m;
+ var error = setpoint - power;
+ var controlOutput = (kp * error) *(1 - Math.Abs((t-307.5m)/7.5m));
+
+ return controlOutput;
+
+ // var a = holdZone - maxAllowedTemp;
+ // var b = -a * maxAllowedTemp;
+ }
internal static Decimal CalcMaxChargePower(this ModbusRegisters data)
{
@@ -133,13 +149,15 @@ public static class BatteryDataParser
{
var v = ReadVoltage(data);
var i = ReadCurrent(data);
+ var t = data.ParseDecimal(register: 1004, scaleFactor: 0.1m, offset: -400);
var pLimits = new[]
{
CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMin, Constants.RIntMin),
CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMin, Constants.RIntMax),
CalcPowerLimitImposedByCurrentLimit(v, i, -Constants.IMax, Constants.RIntMin),
- CalcPowerLimitImposedByCurrentLimit(v, i, -Constants.IMax, Constants.RIntMax)
+ CalcPowerLimitImposedByCurrentLimit(v, i, -Constants.IMax, Constants.RIntMax),
+ // CalcPowerLimitImposedByTempLimit(t,315,300)
};
var pLimit = pLimits.Max();
diff --git a/csharp/lib/Devices/Battery48TL/Constants.cs b/csharp/lib/Devices/Battery48TL/Constants.cs
index 11432630b..44234a09c 100644
--- a/csharp/lib/Devices/Battery48TL/Constants.cs
+++ b/csharp/lib/Devices/Battery48TL/Constants.cs
@@ -28,8 +28,5 @@ public static class Constants
public const Decimal RIntMin = RStringMin / NumberOfStrings;
public const Decimal RIntMax = RStringMax / NumberOfStrings;
- public const Decimal IMax = NumberOfStrings * IMaxPerString;
-
-
-
+ public const Decimal IMax = NumberOfStrings * IMaxPerString;
}
\ No newline at end of file
diff --git a/csharp/lib/Devices/EmuMeter/EmuMeter.csproj b/csharp/lib/Devices/EmuMeter/EmuMeter.csproj
index 5b129bb85..c05adbe6b 100644
--- a/csharp/lib/Devices/EmuMeter/EmuMeter.csproj
+++ b/csharp/lib/Devices/EmuMeter/EmuMeter.csproj
@@ -9,6 +9,7 @@
+
diff --git a/csharp/lib/Devices/Trumpf/TruConvertAc/TruConvertAc.csproj b/csharp/lib/Devices/Trumpf/TruConvertAc/TruConvertAc.csproj
index d8eb3e3d3..31669d385 100644
--- a/csharp/lib/Devices/Trumpf/TruConvertAc/TruConvertAc.csproj
+++ b/csharp/lib/Devices/Trumpf/TruConvertAc/TruConvertAc.csproj
@@ -9,6 +9,7 @@
+
diff --git a/csharp/lib/Devices/Trumpf/TruConvertAc/TruConvertAcControl.cs b/csharp/lib/Devices/Trumpf/TruConvertAc/TruConvertAcControl.cs
index 137549fbf..74fb87c3a 100644
--- a/csharp/lib/Devices/Trumpf/TruConvertAc/TruConvertAcControl.cs
+++ b/csharp/lib/Devices/Trumpf/TruConvertAc/TruConvertAcControl.cs
@@ -31,7 +31,7 @@ public record TruConvertAcControl
public AcErrorPolicy ErrorHandlingPolicy { get; init;} = 0;
public AcDcGridType GridType { get; init;} = 0;
public UInt16 SubSlaveAddress { get; init;} = 0;
- public Boolean UseModbusSlaveIdForAddressing { get; init;} = false;
+ public Boolean UseModbusSlaveIdForAddressing { get; init;} = false;
public UInt16 SubSlaveErrorPolicy { get; init;} = 0; // must be an enum
public Decimal SignedPowerNominalValue { get; init;} = 0; // resolution 0.001 and Unit kva,
public Decimal SignedPowerSetValueL1 { get; init;} = 0; // resolution 0.001 and Unit kva,
@@ -63,9 +63,9 @@ public record TruConvertAcControl
public Decimal MaxPeakCurrentVoltageControlL2 { get; init;} = 0; // resolution 0.01
public Decimal MaxPeakCurrentVoltageControlL3 { get; init;} = 0; // resolution 0.01
public UInt16 GridFormingMode { get; init;} = 1; // 0 = not grid-forming (grid-tied) ,1 = grid-forming
- public UInt16 DcLinkRefVoltage { get; init;} = 850;
- public UInt16 DcLinkMinVoltage { get; init;} = 830;
- public UInt16 DcLinkMaxVoltage { get; init;} = 870;
+ public UInt16 DcLinkRefVoltage { get; init;} = 800;
+ public UInt16 DcLinkMinVoltage { get; init;} = 780;
+ public UInt16 DcLinkMaxVoltage { get; init;} = 820;
public UInt16 DcVoltageRefUs { get; init;} = 900;
public UInt16 DcMinVoltageUs { get; init;} = 880;
public UInt16 DcMaxVoltageUs { get; init;} = 920;
diff --git a/csharp/lib/Devices/Trumpf/TruConvertAc/TruConvertAcDevice.cs b/csharp/lib/Devices/Trumpf/TruConvertAc/TruConvertAcDevice.cs
index 255fc91aa..04c1ed26f 100644
--- a/csharp/lib/Devices/Trumpf/TruConvertAc/TruConvertAcDevice.cs
+++ b/csharp/lib/Devices/Trumpf/TruConvertAc/TruConvertAcDevice.cs
@@ -2,7 +2,10 @@ using System.Diagnostics.CodeAnalysis;
using InnovEnergy.Lib.Devices.Trumpf.TruConvert;
using InnovEnergy.Lib.Protocols.Modbus.Clients;
using InnovEnergy.Lib.Protocols.Modbus.Connections;
+using InnovEnergy.Lib.StatusApi.Connections;
+using InnovEnergy.Lib.StatusApi.Phases;
using InnovEnergy.Lib.Utils;
+using static DecimalMath.DecimalEx;
using static InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.AcControlRegisters;
@@ -39,6 +42,8 @@ public class TruConvertAcDevice
WriteRegs(CommunicationTimeout, c.CommunicationTimeout.TotalSeconds.ConvertTo());
WriteRegs(ConnectedSystemConfig, c.ConnectedSystemConfig);
+
+
WriteCoils(PowerStageConfig, c.PowerStageEnable,
c.SetValueConfig.ConvertTo(),
c.ResetsAlarmAndWarning);
@@ -91,6 +96,8 @@ public class TruConvertAcDevice
private void WriteRegs (UInt16 a, params IConvertible[] regs) => ModbusTcpClient.WriteRegisters(a, regs.Select(v => v.ConvertTo()).ToArray());
private void WriteRegs (UInt16 a, params UInt16[] regs) => ModbusTcpClient.WriteRegisters(a, regs);
private void WriteCoils(UInt16 a, params Boolean[] coils) => ModbusTcpClient.WriteMultipleCoils(a, coils);
+
+ private static Decimal GetPhi(Decimal cosPhi) => cosPhi.Clamp(-1m, 1m).Apply(ACos);
public TruConvertAcStatus? ReadStatus()
{
@@ -112,115 +119,171 @@ public class TruConvertAcDevice
{
// Console.WriteLine("Reading Ac Device");
- var acActualMain = ModbusTcpClient.ReadInputRegisters(5001, 3);
- var acActualAcDc = ModbusTcpClient.ReadInputRegisters(5021, 9);
- var acActualAcDc2 = ModbusTcpClient.ReadInputRegisters(5031, 1);
- var acActualAcDc3 = ModbusTcpClient.ReadInputRegisters(5131, 6);
- var acActualMeasurement = ModbusTcpClient.ReadInputRegisters(5141, 3);
- var acActualMeasurement1 = ModbusTcpClient.ReadInputRegisters(5151, 3);
- var acActualMeasurement2 = ModbusTcpClient.ReadInputRegisters(5161, 3);
- var acActualMeasurement3 = ModbusTcpClient.ReadInputRegisters(5171, 3);
- var acActualMeasurement4 = ModbusTcpClient.ReadInputRegisters(5187, 2);
- var acActualMeasurement5 = ModbusTcpClient.ReadInputRegisters(5189, 2);
- var acActualMeasurement6 = ModbusTcpClient.ReadInputRegisters(5191, 2);
- var acActualMeasurement7 = ModbusTcpClient.ReadInputRegisters(5201, 1);
- var acActualMeasurement8 = ModbusTcpClient.ReadInputRegisters(5211, 4);
- var acActualMeasurement9 = ModbusTcpClient.ReadInputRegisters(5221, 2);
- var acActualTemp = ModbusTcpClient.ReadInputRegisters(5501, 1);
- var acWarningValues = ModbusTcpClient.ReadInputRegisters(2402, 22);
- var acAlarmValues = ModbusTcpClient.ReadInputRegisters(2809, 22);
- var acSetValues = ModbusTcpClient.ReadInputRegisters(4196, 1);
+ var acSerialNumber = ModbusTcpClient.ReadInputRegisters(2009, 2);
+ var acActualMain = ModbusTcpClient.ReadInputRegisters(5001, 3);
+ var acActualAcDc = ModbusTcpClient.ReadInputRegisters(5021, 9);
+ var acActualAcDc2 = ModbusTcpClient.ReadInputRegisters(5031, 1);
+ var acActualAcDc3 = ModbusTcpClient.ReadInputRegisters(5131, 6);
+ var acActualMeasurement = ModbusTcpClient.ReadInputRegisters(5141, 3);
+ var acActualMeasurement1 = ModbusTcpClient.ReadInputRegisters(5151, 3);
+ var acActualMeasurement2 = ModbusTcpClient.ReadInputRegisters(5161, 3);
+ var acActualMeasurement3 = ModbusTcpClient.ReadInputRegisters(5171, 3);
+ var acActualMeasurement4 = ModbusTcpClient.ReadInputRegisters(5187, 2);
+ var acActualMeasurement5 = ModbusTcpClient.ReadInputRegisters(5189, 2);
+ var acActualMeasurement6 = ModbusTcpClient.ReadInputRegisters(5191, 2);
+ var acActualMeasurement7 = ModbusTcpClient.ReadInputRegisters(5201, 1);
+ var acActualMeasurement8 = ModbusTcpClient.ReadInputRegisters(5211, 4);
+ var acActualMeasurement9 = ModbusTcpClient.ReadInputRegisters(5221, 2);
+ var acActualTemp = ModbusTcpClient.ReadInputRegisters(5501, 1);
+ var acWarningValues = ModbusTcpClient.ReadInputRegisters(2402, 22);
+ var acAlarmValues = ModbusTcpClient.ReadInputRegisters(2809, 22);
+ var acSetValues = ModbusTcpClient.ReadInputRegisters(4196, 1);
var warnings = Enumerable
- .Range(2404, 20)
- .Select(n => acWarningValues.GetUInt16((UInt16)n).ConvertTo())
- .ToArray();
+ .Range(2404, 20)
+ .Select(n => acWarningValues.GetUInt16((UInt16)n).ConvertTo())
+ .ToArray();
var alarms = Enumerable
- .Range(2811, 20)
- .Select(n => acAlarmValues.GetUInt16((UInt16)n).ConvertTo())
- .Where(m => m != AlarmMessage.NoAlarm)
- .ToArray();
+ .Range(2811, 20)
+ .Select(n => acAlarmValues.GetUInt16((UInt16)n).ConvertTo())
+ .Where(m => m != AlarmMessage.NoAlarm)
+ .ToArray();
+ var dcPower = acActualMeasurement.GetInt16(5141) * 1m + acActualMeasurement.GetInt16(5142) * 1m + acActualMeasurement.GetInt16(5143) * 1m;
+ var dcVoltage = acActualMeasurement8.GetUInt16(5214) + acActualMeasurement8.GetUInt16(5213);
+ var dcCurrent = dcVoltage != 0m
+ ? dcPower / dcVoltage
+ : 0m;
+
+
+ // //acActualMeasurement
+ // PowerAcL1 = acActualMeasurement.GetInt16(5141) * 1m, // in Watt
+ // PowerAcL2 = acActualMeasurement.GetInt16(5142) * 1m, // in Watt
+ // PowerAcL3 = acActualMeasurement.GetInt16(5143) * 1m, // in Watt
+ //
+ //acActualMeasurement1
+ // PhaseCurrentL1 = acActualMeasurement1.GetUInt16(5151) * 0.01m,
+ // PhaseCurrentL2 = acActualMeasurement1.GetUInt16(5152) * 0.01m,
+ // PhaseCurrentL3 = acActualMeasurement1.GetUInt16(5153) * 0.01m,
+
+ //acActualMeasurement2
+ // GridVoltageL1 = acActualMeasurement2.GetUInt16(5161) * 0.1m,
+ // GridVoltageL2 = acActualMeasurement2.GetUInt16(5162) * 0.1m,
+ // GridVoltageL3 = acActualMeasurement2.GetUInt16(5163) * 0.1m,
+
+ //acActualMeasurement3
+ // CosPhiL1 = acActualMeasurement3.GetInt16(5171) * 0.01m,
+ // CosPhiL2 = acActualMeasurement3.GetInt16(5172) * 0.01m,
+ // CosPhiL3 = acActualMeasurement3.GetInt16(5173) * 0.01m,
+
+ // //acActualMeasurement4
+ // SumPowerL1 = acActualMeasurement4.GetUInt32(5187) * 1m, // in Watt
+ // //acActualMeasurement5
+ // SumPowerL2 = acActualMeasurement5.GetUInt32(5189) * 1m, // in Watt
+ // //acActualMeasurement6
+ // SumPowerL3 = acActualMeasurement6.GetUInt32(5191) * 1m, // in Watt
+ // //acActualMeasurement9
+ // GridFrequency = acActualMeasurement7.GetInt16(5201) * 0.01m,
+
+ //acActualMeasurement11
+ // VoltageIntNtoPE = acActualMeasurement9.GetInt16(5221) * 0.1m,
+ // VoltageExtNtoPE = acActualMeasurement9.GetInt16(5222) * 0.1m,
+
+ //
+ // ApparentPowerAcL1 = acActualAcDc3.GetUInt16(5131) * 1m, // in VA
+ // ApparentPowerAcL2 = acActualAcDc3.GetUInt16(5132) * 1m, // in VA
+ // ApparentPowerAcL3 = acActualAcDc3.GetUInt16(5133) * 1m, // in VA
+
+ var apparentPowerAcL1 = acActualAcDc3.GetUInt16(5131) * 1m;
+ var apparentPowerAcL2 = acActualAcDc3.GetUInt16(5132) * 1m;
+ var apparentPowerAcL3 = acActualAcDc3.GetUInt16(5133) * 1m;
+
+ var powerAcL1 = acActualMeasurement.GetInt16(5141) * 1m; // in Watt
+ var powerAcL2 = acActualMeasurement.GetInt16(5142) * 1m; // in Watt
+ var powerAcL3 = acActualMeasurement.GetInt16(5143) * 1m; // in Watt
+
+ var phaseCurrentL1 = acActualMeasurement1.GetUInt16(5151) * 0.01m;
+ var phaseCurrentL2 = acActualMeasurement1.GetUInt16(5152) * 0.01m;
+ var phaseCurrentL3 = acActualMeasurement1.GetUInt16(5153) * 0.01m;
+
+ var gridVoltageL1 = acActualMeasurement2.GetUInt16(5161) * 0.1m;
+ var gridVoltageL2 = acActualMeasurement2.GetUInt16(5162) * 0.1m;
+ var gridVoltageL3 = acActualMeasurement2.GetUInt16(5163) * 0.1m;
+
+ var gridFrequency = acActualMeasurement7.GetInt16(5201) * 0.01m;
+
return new TruConvertAcStatus
- {
+ (
+ Ac: new ThreePhaseAcConnection
+ (
+ AcPhase.FromActiveReactive(
+ activePower: powerAcL1,
+ apparentPower: apparentPowerAcL1,
+ voltage: gridVoltageL1,
+ current: phaseCurrentL1),
+
+ AcPhase.FromActiveReactive(
+ activePower: powerAcL2,
+ apparentPower: apparentPowerAcL2,
+ voltage: gridVoltageL2,
+ current: phaseCurrentL2),
+
+ AcPhase.FromActiveReactive(
+ activePower: powerAcL3,
+ apparentPower: apparentPowerAcL3,
+ voltage: gridVoltageL3,
+ current: phaseCurrentL3),
+
+ gridFrequency // Gird Frequency
+ ),
+
+
+ Dc: new DcConnection
+ (
+ dcVoltage,
+ dcCurrent
+ ),
+
+ SerialNumber : acSerialNumber.GetInt32(2009).ToString(),
+
// acActualMainValues
- MainState = acActualMain.GetInt16(5001).ConvertTo(),
- NumberOfConnectedSlaves = acActualMain.GetUInt16(5002),
- NumberOfConnectedSubSlaves = acActualMain.GetUInt16(5003),
-
+ MainState : acActualMain.GetInt16(5001).ConvertTo(),
+ NumberOfConnectedSlaves : acActualMain.GetUInt16(5002),
+ NumberOfConnectedSubSlaves : acActualMain.GetUInt16(5003),
+
//acActualAcDc
- AcDcNominalGridFrequency = acActualAcDc.GetUInt16(5021) * 0.1m,
- AcDcNominalGridVoltage = acActualAcDc.GetUInt16(5022),
- AcDcActNominalPower = acActualAcDc.GetUInt16(5023),
- AcDcActiveGridType = acActualAcDc.GetUInt16(5024).ConvertTo(),
- AcDcPowerLimitingStatusAct = acActualAcDc.GetUInt16(5025),
- AcDcDcVoltageReference = acActualAcDc.GetUInt16(5026), // DC link reference
- AcDcDcLinkVoltageMinAct = acActualAcDc.GetUInt16(5027), // DC link min voltage
- AcDcDcLinkVoltageMaxAct = acActualAcDc.GetUInt16(5028), // DC link max voltage
- AcDcDcLinkChargedMinVoltage = acActualAcDc.GetUInt16(5029) * 0.01m,
+ AcDcNominalGridFrequency : acActualAcDc.GetUInt16(5021) * 0.1m,
+ AcDcNominalGridVoltage : acActualAcDc.GetUInt16(5022),
+ AcDcActNominalPower : acActualAcDc.GetUInt16(5023),
+ AcDcActiveGridType : acActualAcDc.GetUInt16(5024).ConvertTo(),
+ AcDcPowerLimitingStatusAct : acActualAcDc.GetUInt16(5025),
+ AcDcDcVoltageReference : acActualAcDc.GetUInt16(5026), // DC link reference
+ AcDcDcLinkVoltageMinAct : acActualAcDc.GetUInt16(5027), // DC link min voltage
+ AcDcDcLinkVoltageMaxAct : acActualAcDc.GetUInt16(5028), // DC link max voltage
+ AcDcDcLinkChargedMinVoltage : acActualAcDc.GetUInt16(5029) * 0.01m,
+
//ac Actual AcDc 2
- AcDcStmActCustomer = acActualAcDc2.GetUInt16(5031), //need to check
-
- ApparentPowerAcL1 = acActualAcDc3.GetUInt16(5131) * 1m, // in VA
- ApparentPowerAcL2 = acActualAcDc3.GetUInt16(5132) * 1m, // in VA
- ApparentPowerAcL3 = acActualAcDc3.GetUInt16(5133) * 1m, // in VA
-
- AcDcOverloadIntegratorStatusL1 = acActualAcDc3.GetUInt16(5134) * 0.1m,
- AcDcOverloadIntegratorStatusL2 = acActualAcDc3.GetUInt16(5135) * 0.1m,
- AcDcOverloadIntegratorStatusL3 = acActualAcDc3.GetUInt16(5136) * 0.1m,
-
- //acActualMeasurement
- PowerAcL1 = acActualMeasurement.GetInt16(5141) * 1m, // in Watt
- PowerAcL2 = acActualMeasurement.GetInt16(5142) * 1m, // in Watt
- PowerAcL3 = acActualMeasurement.GetInt16(5143) * 1m, // in Watt
-
- //acActualMeasurement1
- PhaseCurrentL1 = acActualMeasurement1.GetUInt16(5151) * 0.01m,
- PhaseCurrentL2 = acActualMeasurement1.GetUInt16(5152) * 0.01m,
- PhaseCurrentL3 = acActualMeasurement1.GetUInt16(5153) * 0.01m,
-
- //acActualMeasurement2
- GridVoltageL1 = acActualMeasurement2.GetUInt16(5161) * 0.1m,
- GridVoltageL2 = acActualMeasurement2.GetUInt16(5162) * 0.1m,
- GridVoltageL3 = acActualMeasurement2.GetUInt16(5163) * 0.1m,
-
- //acActualMeasurement3
- CosPhiL1 = acActualMeasurement3.GetInt16(5171) * 0.01m,
- CosPhiL2 = acActualMeasurement3.GetInt16(5172) * 0.01m,
- CosPhiL3 = acActualMeasurement3.GetInt16(5173) * 0.01m,
-
- //acActualMeasurement4
- SumPowerL1 = acActualMeasurement4.GetUInt32(5187) * 1m, // in Watt
-
- //acActualMeasurement5
- SumPowerL2 = acActualMeasurement5.GetUInt32(5189) * 1m, // in Watt
-
- //acActualMeasurement6
- SumPowerL3 = acActualMeasurement6.GetUInt32(5191) * 1m, // in Watt
-
- //acActualMeasurement9
- GridFrequency = acActualMeasurement7.GetInt16(5201) * 0.01m,
+ AcDcStmActCustomer : acActualAcDc2.GetUInt16(5031), //need to check
+ AcDcOverloadIntegratorStatusL1 : acActualAcDc3.GetUInt16(5134) * 0.1m,
+ AcDcOverloadIntegratorStatusL2 : acActualAcDc3.GetUInt16(5135) * 0.1m,
+ AcDcOverloadIntegratorStatusL3 : acActualAcDc3.GetUInt16(5136) * 0.1m,
+ AcSignedPowerValue : acSetValues.GetInt16(4196) * -1.0m, // this is also used for control
//acActualMeasurement10
- ActualDcLinkVoltageUpperHalf = acActualMeasurement8.GetUInt16(5211),
- ActualDcLinkVoltageLowerHalf = acActualMeasurement8.GetUInt16(5212),
- ActualDcLinkVoltageUpperHalfExt = acActualMeasurement8.GetUInt16(5213),
- ActualDcLinkVoltageLowerHalfExt = acActualMeasurement8.GetUInt16(5214),
-
- //acActualMeasurement11
- VoltageIntNtoPE = acActualMeasurement9.GetInt16(5221) * 0.1m,
- VoltageExtNtoPE = acActualMeasurement9.GetInt16(5222) * 0.1m,
-
- //acActualTemp
- InletAirTemperature = acActualTemp.GetInt16(5501) * 0.1m,
+ ActualDcLinkVoltageUpperHalf : acActualMeasurement8.GetUInt16(5211),
+ ActualDcLinkVoltageLowerHalf : acActualMeasurement8.GetUInt16(5212),
+ ActualDcLinkVoltageUpperHalfExt : acActualMeasurement8.GetUInt16(5213),
+ ActualDcLinkVoltageLowerHalfExt : acActualMeasurement8.GetUInt16(5214),
- Warnings = warnings,
- Alarms = alarms,
+ VoltageIntNtoPe : acActualMeasurement9.GetInt16(5221) * 0.1m,
+ VoltageExtNtoPe : acActualMeasurement9.GetInt16(5222) * 0.1m,
+ //acActualTemp
+ InletAirTemperature : acActualTemp.GetInt16(5501) * 0.1m,
- // acSetValues
- AcSignedPowerValue = acSetValues.GetInt16(4196) * -1.0m, // this is also used for control
- };
+ Warnings : warnings,
+ Alarms : alarms
+ );
}
}
\ No newline at end of file
diff --git a/csharp/lib/Devices/Trumpf/TruConvertAc/TruConvertAcStatus.cs b/csharp/lib/Devices/Trumpf/TruConvertAc/TruConvertAcStatus.cs
index 64c5ea4c8..8f2047ebb 100644
--- a/csharp/lib/Devices/Trumpf/TruConvertAc/TruConvertAcStatus.cs
+++ b/csharp/lib/Devices/Trumpf/TruConvertAc/TruConvertAcStatus.cs
@@ -1,60 +1,43 @@
-using System.Diagnostics.CodeAnalysis;
using InnovEnergy.Lib.Devices.Trumpf.TruConvert;
+using InnovEnergy.Lib.StatusApi.Connections;
+using InnovEnergy.Lib.StatusApi.Devices;
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc;
using AlarmMessages = IReadOnlyList;
using WarningMessages = IReadOnlyList;
-[SuppressMessage("ReSharper", "InconsistentNaming")]
public record TruConvertAcStatus
+(
+ ThreePhaseAcConnection Ac,
+ DcConnection Dc,
+ String SerialNumber,
+ MainState MainState,
+ UInt16 NumberOfConnectedSlaves,
+ UInt16 NumberOfConnectedSubSlaves,
+ Decimal AcDcNominalGridFrequency,
+ Decimal AcDcNominalGridVoltage,
+ Decimal AcDcActNominalPower,
+ AcDcGridType AcDcActiveGridType,
+ Decimal AcDcPowerLimitingStatusAct,
+ Decimal AcDcDcVoltageReference,
+ Decimal AcDcDcLinkVoltageMinAct,
+ Decimal AcDcDcLinkVoltageMaxAct,
+ Decimal AcDcDcLinkChargedMinVoltage,
+ Decimal AcDcStmActCustomer,
+ Decimal AcDcOverloadIntegratorStatusL1,
+ Decimal AcDcOverloadIntegratorStatusL2,
+ Decimal AcDcOverloadIntegratorStatusL3,
+ Decimal AcSignedPowerValue,
+ Decimal ActualDcLinkVoltageUpperHalf,
+ Decimal ActualDcLinkVoltageLowerHalf,
+ Decimal ActualDcLinkVoltageUpperHalfExt,
+ Decimal ActualDcLinkVoltageLowerHalfExt,
+ Decimal VoltageIntNtoPe,
+ Decimal VoltageExtNtoPe,
+ Decimal InletAirTemperature,
+ WarningMessages Warnings,
+ AlarmMessages Alarms
+) : ThreePhaseInverter(Ac, Dc)
{
- public MainState MainState { get; init; } // 5000
- public UInt16 NumberOfConnectedSlaves { get; init; } // 5001
- public UInt16 NumberOfConnectedSubSlaves { get; init; }
- public Decimal AcDcNominalGridFrequency { get; init; }
- public Decimal AcDcNominalGridVoltage { get; init; }
- public Decimal AcDcActNominalPower { get; init; }
- public AcDcGridType AcDcActiveGridType { get; init; }
- public Decimal AcDcPowerLimitingStatusAct { get; init; }
- public Decimal AcDcDcVoltageReference { get; init; }
- public Decimal AcDcDcLinkVoltageMinAct { get; init; }
- public Decimal AcDcDcLinkVoltageMaxAct { get; init; }
- public Decimal AcDcDcLinkChargedMinVoltage { get; init; }
- public Decimal AcDcStmActCustomer { get; init; }
- public Decimal ApparentPowerAcL1 { get; init; }
- public Decimal ApparentPowerAcL2 { get; init; }
- public Decimal ApparentPowerAcL3 { get; init; }
- public Decimal AcDcOverloadIntegratorStatusL1 { get; init; }
- public Decimal AcDcOverloadIntegratorStatusL2 { get; init; }
- public Decimal AcDcOverloadIntegratorStatusL3 { get; init; }
- public Decimal PowerAcL1 { get; init; }
- public Decimal PowerAcL2 { get; init; }
- public Decimal PowerAcL3 { get; init; }
- public Decimal PhaseCurrentL1 { get; init; }
- public Decimal PhaseCurrentL2 { get; init; }
- public Decimal PhaseCurrentL3 { get; init; }
- public Decimal GridVoltageL1 { get; init; }
- public Decimal GridVoltageL2 { get; init; }
- public Decimal GridVoltageL3 { get; init; }
- public Decimal CosPhiL1 { get; init; }
- public Decimal CosPhiL2 { get; init; }
- public Decimal CosPhiL3 { get; init; }
- public Decimal SumPowerL1 { get; init; }
- public Decimal SumPowerL2 { get; init; }
- public Decimal SumPowerL3 { get; init; }
- public Decimal GridFrequency { get; init; }
- public Decimal ActualDcLinkVoltageUpperHalf { get; init; }
- public Decimal ActualDcLinkVoltageLowerHalf { get; init; }
- public Decimal ActualDcLinkVoltageUpperHalfExt { get; init; }
- public Decimal ActualDcLinkVoltageLowerHalfExt { get; init; }
- public Decimal VoltageIntNtoPE { get; init; }
- public Decimal VoltageExtNtoPE { get; init; }
- public Decimal InletAirTemperature { get; init; }
- public WarningMessages Warnings { get; init; } = Array.Empty();
- public AlarmMessages Alarms { get; init; } = Array.Empty();
- public Boolean PowerOperation { get; init; }
- public Decimal AcSignedPowerValue { get; init; }// this is in control but we also need to read data
- //public Int16 AcSignedPowerValue2 { get; init; } = 0; // For Test
-
}
\ No newline at end of file
diff --git a/csharp/lib/Devices/Trumpf/TruConvertDc/TruConvertDc.csproj b/csharp/lib/Devices/Trumpf/TruConvertDc/TruConvertDc.csproj
index 1dde32bd0..c2acc0062 100644
--- a/csharp/lib/Devices/Trumpf/TruConvertDc/TruConvertDc.csproj
+++ b/csharp/lib/Devices/Trumpf/TruConvertDc/TruConvertDc.csproj
@@ -10,6 +10,7 @@
+
diff --git a/csharp/lib/Devices/Trumpf/TruConvertDc/TruConvertDcControl.cs b/csharp/lib/Devices/Trumpf/TruConvertDc/TruConvertDcControl.cs
index 9d01f9f8e..82a4e4dcc 100644
--- a/csharp/lib/Devices/Trumpf/TruConvertDc/TruConvertDcControl.cs
+++ b/csharp/lib/Devices/Trumpf/TruConvertDc/TruConvertDcControl.cs
@@ -12,7 +12,6 @@ public record TruConvertDcControl
public Boolean ResetParamToDefault { get; init;} = false ; // Coil
public TimeSpan TimeoutForCommunication { get; init;} = DefaultCommunicationTimeOut;
public Boolean RestartFlag { get; init;} = false ; // Coil
-
public SystemConfig ConnectedSystemConfig { get; init;} = SystemConfig.NoConfig ;
public UInt16 UpdateSwTrigger { get; init;} = 0 ;
public UInt16 AutomaticSwUpdate { get; init;} = 0 ;
@@ -36,9 +35,9 @@ public record TruConvertDcControl
public Decimal BatteryCurrentSet { get; init;} = 0; // resolution 1.0
public Decimal DynamicCurrentPerMillisecond { get; init;} = 0; // resolution : 0.01
public Decimal DcLinkControlMode { get; init;} = 0; // Parameter aktiviert/deaktiviert "DC link voltage droop mode"
- public Decimal ReferenceVoltage { get; init;} = 0; // resolution : 0.1
- public Decimal UpperVoltageWindow { get; init;} = 0; // resolution : 0.1
- public Decimal LowerVoltageWindow { get; init;} = 0; // resolution : 0.1
+ public Decimal ReferenceVoltage { get; init;} = 800; // resolution : 0.1
+ public Decimal UpperVoltageWindow { get; init;} = 40; // resolution : 0.1
+ public Decimal LowerVoltageWindow { get; init;} = 40; // resolution : 0.1
public Decimal VoltageDeadBand { get; init;} = 0; // resolution : 0.1
private static readonly TimeSpan DefaultCommunicationTimeOut = TimeSpan.FromMinutes(10);
diff --git a/csharp/lib/Devices/Trumpf/TruConvertDc/TruConvertDcDevice.cs b/csharp/lib/Devices/Trumpf/TruConvertDc/TruConvertDcDevice.cs
index f7649a8c0..89cd675ce 100644
--- a/csharp/lib/Devices/Trumpf/TruConvertDc/TruConvertDcDevice.cs
+++ b/csharp/lib/Devices/Trumpf/TruConvertDc/TruConvertDcDevice.cs
@@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis;
using InnovEnergy.Lib.Devices.Trumpf.TruConvert;
using InnovEnergy.Lib.Protocols.Modbus.Clients;
using InnovEnergy.Lib.Protocols.Modbus.Connections;
+using InnovEnergy.Lib.StatusApi.Connections;
using InnovEnergy.Lib.Utils;
using static InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.DcControlRegisters;
@@ -42,6 +43,7 @@ public class TruConvertDcDevice
*/
// TODO starting from 4000, evaluate what/if needs updating below 4000
+ WriteRegs(TimeoutCommunication, c.TimeoutForCommunication.TotalSeconds.ConvertTo());
WriteCoils(PowerStageOperation, c.PowerStageEnable);
WriteCoils(ResetsAlarmAndWarning, c.ResetsAlarmAndWarning);
@@ -103,18 +105,14 @@ public class TruConvertDcDevice
private TruConvertDcStatus TryReadStatus()
{
// Console.WriteLine("Reading DC Device");
-
var dcPrValMain = ModbusTcpClient.ReadInputRegisters(5001, 3);
var dcBatteryValue = ModbusTcpClient.ReadInputRegisters(5101, 1);
var dcBatteryValue2 = ModbusTcpClient.ReadInputRegisters(5111, 1);
var dcBatteryValue3 = ModbusTcpClient.ReadInputRegisters(5114, 2);
- var dcBatteryValue4 = ModbusTcpClient.ReadInputRegisters(5121, 1);
-
+ var dcBatteryValue4 = ModbusTcpClient.ReadInputRegisters(5121, 1);
var dcPrValDcDc = ModbusTcpClient.ReadInputRegisters(5124, 1);
var dcPrValDcDc2 = ModbusTcpClient.ReadInputRegisters(5127, 2);
-
var dcTempValue = ModbusTcpClient.ReadInputRegisters(5511, 1);
-
var dcWarningValues = ModbusTcpClient.ReadInputRegisters(2404, 20);
var dcAlarmValues = ModbusTcpClient.ReadInputRegisters(2811, 20);
var dcSetValues = ModbusTcpClient.ReadInputRegisters(4001, 1);
@@ -133,37 +131,34 @@ public class TruConvertDcDevice
var dcCurrentLimitState = GetFlags(dcPrValDcDc.GetUInt16(5124)).ToArray();
+ var dcLinkVoltage = dcPrValDcDc2.GetUInt16(5128);
+
+ var dcPower = dcBatteryValue4.GetInt16(5121) * 1m;
+
+ var dcCurrent = dcLinkVoltage != 0m ? dcPower / dcLinkVoltage : 0m;
+
return new TruConvertDcStatus
- {
- // dcPrValMain
- MainState = (MainState) dcPrValMain.GetInt16(5001),
- NumberOfConnectedSlaves = dcPrValMain.GetUInt16(5002),
- NumberOfConnectedSubSlaves = dcPrValMain.GetUInt16(5003),
+ (
- // dcBatteryValue
- BatteryVoltage = dcBatteryValue.GetUInt16(5101) * 0.1m,
- BatteryCurrent = dcBatteryValue2.GetInt16(5111),
+ Dc: new DcConnection
+ (
+ dcLinkVoltage,
+ dcCurrent
+ ),
- TotalDcPower = dcBatteryValue3.GetInt32(5114) * 1m, // Resolution is 0.001 (kW) in Tru convert DC doc, but we want it in W
-
- DcPower = dcBatteryValue4.GetInt16(5121) * 1m, // Resolution is 0.001 (kW) in Tru convert DC doc, but we want it in W
-
- // dcPrValDcDc
- StatusOfCurrentLimiting = dcCurrentLimitState,
-
- // dcPrValDcDc2
- OverloadCapacity = dcPrValDcDc2.GetUInt16(5127) * 0.1m,
- DcLinkVoltage = dcPrValDcDc2.GetUInt16(5128),
-
- //dcTempValue
- DcDcInletTemperature = dcTempValue.GetInt16(5511),
-
- Warnings = warnings,
- Alarms = alarms,
-
- // dcSetValues
- PowerOperation = dcSetValues.GetBoolean(4001)
- };
+ MainState : (MainState)dcPrValMain.GetInt16(5001),
+ NumberOfConnectedSlaves : dcPrValMain.GetUInt16(5002),
+ NumberOfConnectedSubSlaves : dcPrValMain.GetUInt16(5003),
+ BatteryVoltage : dcBatteryValue.GetUInt16(5101) * 0.1m,
+ BatteryCurrent : dcBatteryValue2.GetInt16(5111),
+ TotalDcPower : dcBatteryValue3.GetInt32(5114) * 1m, // Resolution is 0.001 (kW) in Tru convert DC doc, but we want it in W
+ StatusOfCurrentLimiting : dcCurrentLimitState,
+ OverloadCapacity : dcPrValDcDc2.GetUInt16(5127) * 0.1m,
+ DcDcInletTemperature : dcTempValue.GetInt16(5511),
+ Warnings : warnings,
+ Alarms : alarms,
+ PowerOperation : dcSetValues.GetBoolean(4001)
+ );
}
}
\ No newline at end of file
diff --git a/csharp/lib/Devices/Trumpf/TruConvertDc/TruConvertDcStatus.cs b/csharp/lib/Devices/Trumpf/TruConvertDc/TruConvertDcStatus.cs
index ae92598bf..88551dee1 100644
--- a/csharp/lib/Devices/Trumpf/TruConvertDc/TruConvertDcStatus.cs
+++ b/csharp/lib/Devices/Trumpf/TruConvertDc/TruConvertDcStatus.cs
@@ -1,4 +1,6 @@
using InnovEnergy.Lib.Devices.Trumpf.TruConvert;
+using InnovEnergy.Lib.StatusApi.Connections;
+using InnovEnergy.Lib.StatusApi.Devices;
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc;
@@ -6,22 +8,20 @@ using AlarmMessages = IReadOnlyList;
using WarningMessages = IReadOnlyList;
using DcCurrentLimitStates = IReadOnlyList;
-public record TruConvertDcStatus
-{
- public MainState MainState { get; init; }
- public UInt16 NumberOfConnectedSlaves { get; init; }
- public UInt16 NumberOfConnectedSubSlaves { get; init; }
- public Decimal BatteryVoltage { get; init; }
- public Decimal BatteryCurrent { get; init; }
- public Decimal TotalDcPower { get; init; }
- public Decimal DcPower { get; init; }
- public DcCurrentLimitStates StatusOfCurrentLimiting { get; init; } = Array.Empty();
- public Decimal OverloadCapacity { get; init; }
- public Decimal DcLinkVoltage { get; init; }
- public Decimal DcDcInletTemperature { get; init; }
- public AlarmMessages Alarms { get; init; } = Array.Empty();
- public WarningMessages Warnings { get; init; } = Array.Empty();
-
- public Boolean PowerOperation { get; init; }
-
-}
\ No newline at end of file
+public record TruConvertDcStatus
+(
+ DcConnection Dc,
+ MainState MainState,
+ UInt16 NumberOfConnectedSlaves,
+ UInt16 NumberOfConnectedSubSlaves,
+ Decimal BatteryVoltage,
+ Decimal BatteryCurrent,
+ Decimal TotalDcPower,
+ DcCurrentLimitStates StatusOfCurrentLimiting,
+ Decimal OverloadCapacity,
+ Decimal DcDcInletTemperature,
+ AlarmMessages Alarms,
+ WarningMessages Warnings,
+ Boolean PowerOperation
+):DcDevice(Dc)
+{}
\ No newline at end of file
diff --git a/csharp/lib/StatusApi/Connections/DcConnection.cs b/csharp/lib/StatusApi/Connections/DcConnection.cs
index 6810ea291..cac41968d 100644
--- a/csharp/lib/StatusApi/Connections/DcConnection.cs
+++ b/csharp/lib/StatusApi/Connections/DcConnection.cs
@@ -1,9 +1,8 @@
using InnovEnergy.Lib.StatusApi.Phases;
-
namespace InnovEnergy.Lib.StatusApi.Connections;
public record DcConnection(Decimal Voltage, Decimal Current) : Phase(Voltage, Current)
{
- public Decimal Power => Current * Voltage;
+ public Decimal Power => (Current * Voltage).Round3();
}
\ No newline at end of file
diff --git a/csharp/lib/StatusApi/Connections/SinglePhaseAcConnection.cs b/csharp/lib/StatusApi/Connections/SinglePhaseAcConnection.cs
index 2691cc5fa..6b8c57b2d 100644
--- a/csharp/lib/StatusApi/Connections/SinglePhaseAcConnection.cs
+++ b/csharp/lib/StatusApi/Connections/SinglePhaseAcConnection.cs
@@ -3,10 +3,10 @@ using InnovEnergy.Lib.StatusApi.Phases;
namespace InnovEnergy.Lib.StatusApi.Connections;
public record SinglePhaseAcConnection
- (
- Decimal Voltage,
- Decimal Current,
- Decimal Phi,
- Decimal Frequency
- )
- : AcPhase(Voltage, Current, Phi);
\ No newline at end of file
+(
+ Decimal Voltage,
+ Decimal Current,
+ Decimal Phi,
+ Decimal Frequency
+);
+ //: AcPhase(Voltage, Current, Phi);
\ No newline at end of file
diff --git a/csharp/lib/StatusApi/Phases/AcPhase.cs b/csharp/lib/StatusApi/Phases/AcPhase.cs
index 8bb7f8e45..1270527f9 100644
--- a/csharp/lib/StatusApi/Phases/AcPhase.cs
+++ b/csharp/lib/StatusApi/Phases/AcPhase.cs
@@ -21,12 +21,12 @@ public record AcPhase
public static AcPhase FromActiveReactive
(
Decimal activePower,
- Decimal reactivePower,
+ Decimal apparentPower,
Decimal voltage,
Decimal current
)
{
- var apparentPower = Sqrt(activePower * activePower + reactivePower * reactivePower);
+ var reactivePower = Sqrt(Math.Abs(apparentPower * apparentPower - activePower * activePower ));
var phi = ATan2(reactivePower, activePower);
return new AcPhase
@@ -39,11 +39,10 @@ public record AcPhase
ReactivePower: reactivePower,
PowerFactor: Cos(phi)
);
-
}
- public static AcPhase FromVoltageCurrentPhi(Decimal voltage, Decimal current, Decimal phi)
+ public static AcPhase CreateInstance(Decimal voltage, Decimal current, Decimal phi)
{
var powerFactor = Cos(phi);
diff --git a/csharp/lib/StatusApi/Utils.cs b/csharp/lib/StatusApi/Utils.cs
new file mode 100644
index 000000000..b86db8478
--- /dev/null
+++ b/csharp/lib/StatusApi/Utils.cs
@@ -0,0 +1,11 @@
+using InnovEnergy.Lib.Utils;
+
+namespace InnovEnergy.Lib.StatusApi;
+
+public static class Utils
+{
+ public static Decimal Round3(this Decimal d)
+ {
+ return d.RoundToSignificantFigures(3);
+ }
+}
\ No newline at end of file
diff --git a/csharp/lib/Utils/Utils.csproj b/csharp/lib/Utils/Utils.csproj
index a645f2431..0ddcddea5 100644
--- a/csharp/lib/Utils/Utils.csproj
+++ b/csharp/lib/Utils/Utils.csproj
@@ -6,7 +6,7 @@
-
+