Update Status to inherit from Status Api
This commit is contained in:
parent
5affecda55
commit
175f11fccf
|
@ -26,7 +26,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VenusLogger", "app/VenusLog
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meiringen", "app/Meiringen/Meiringen.csproj", "{4C816420-FD19-47BF-87FE-599210CA8384}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meiringen", "app/Meiringen/Meiringen.csproj", "{4C816420-FD19-47BF-87FE-599210CA8384}"
|
||||||
EndProject
|
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
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BmsTunnel", "app/BmsTunnel/BmsTunnel.csproj", "{40B45363-BE34-420B-8F87-775EE6EE3513}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BmsTunnel", "app/BmsTunnel/BmsTunnel.csproj", "{40B45363-BE34-420B-8F87-775EE6EE3513}"
|
||||||
EndProject
|
EndProject
|
||||||
|
@ -34,21 +34,19 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "app", "app", "{145597B4-3E3
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "lib", "lib", "{AD5B98A8-AB7F-4DA2-B66D-5B4E63E7D854}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "lib", "lib", "{AD5B98A8-AB7F-4DA2-B66D-5B4E63E7D854}"
|
||||||
EndProject
|
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
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "deprecated", "deprecated", "{D846B46B-46FF-4EF7-9B9D-DDBEF9533C56}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "deprecated", "deprecated", "{D846B46B-46FF-4EF7-9B9D-DDBEF9533C56}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "deprecated", "deprecated", "{46DE03C4-52D1-47AA-8E60-8BB15361D723}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "deprecated", "deprecated", "{46DE03C4-52D1-47AA-8E60-8BB15361D723}"
|
||||||
EndProject
|
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
|
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
|
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
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GuiFeeder", "app\GuiFeeder\GuiFeeder.csproj", "{5B953EC4-51F3-4A0A-ADF5-BAA3D1570CB2}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatusApi", "lib/StatusApi/StatusApi.csproj", "{9D17E78C-8A70-43DB-A619-DC12D20D023D}"
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatusApi", "lib\StatusApi\StatusApi.csproj", "{9D17E78C-8A70-43DB-A619-DC12D20D023D}"
|
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Devices", "Devices", "{4931A385-24DC-4E78-BFF4-356F8D6D5183}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Devices", "Devices", "{4931A385-24DC-4E78-BFF4-356F8D6D5183}"
|
||||||
EndProject
|
EndProject
|
||||||
|
@ -58,38 +56,36 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Victron", "Victron", "{BD8C
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Trumpf", "Trumpf", "{DDDBEFD0-5DEA-4C7C-A9F2-FDB4636CF092}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Trumpf", "Trumpf", "{DDDBEFD0-5DEA-4C7C-A9F2-FDB4636CF092}"
|
||||||
EndProject
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Battery48TL", "lib\Devices\Battery48TL\Battery48TL.csproj", "{1C3F443A-B339-4B08-80E6-8A84817FFEC9}"
|
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
|
|
||||||
EndProject
|
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
|
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
|
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
|
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
|
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
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FossilTui", "app\FossilTui\FossilTui.csproj", "{C40264BB-C834-4C48-9B3F-6BEF8F37C0ED}"
|
|
||||||
EndProject
|
EndProject
|
||||||
|
|
||||||
Global
|
Global
|
||||||
|
|
|
@ -6,19 +6,15 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\lib\DBus\DBus.csproj" />
|
|
||||||
<ProjectReference Include="..\..\lib\Devices\EmuMeter\EmuMeter.csproj" />
|
<ProjectReference Include="..\..\lib\Devices\EmuMeter\EmuMeter.csproj" />
|
||||||
<ProjectReference Include="..\..\lib\EmuMeter\EmuMeter.csproj" />
|
|
||||||
<ProjectReference Include="..\..\lib\Modbus\Modbus.csproj" />
|
|
||||||
<ProjectReference Include="..\..\lib\Protocols\DBus\DBus.csproj" />
|
<ProjectReference Include="..\..\lib\Protocols\DBus\DBus.csproj" />
|
||||||
<ProjectReference Include="..\..\lib\Protocols\Modbus\Modbus.csproj" />
|
<ProjectReference Include="..\..\lib\Protocols\Modbus\Modbus.csproj" />
|
||||||
<ProjectReference Include="..\..\lib\Utils\Utils.csproj" />
|
<ProjectReference Include="..\..\lib\Utils\Utils.csproj" />
|
||||||
<ProjectReference Include="..\..\lib\VeDBus\VeDBus.csproj" />
|
|
||||||
<ProjectReference Include="..\..\lib\Victron\VeDBus\VeDBus.csproj" />
|
<ProjectReference Include="..\..\lib\Victron\VeDBus\VeDBus.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CliWrap" Version="3.5.0" />
|
<PackageReference Include="CliWrap" Version="3.6.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -15,12 +15,16 @@
|
||||||
<ProjectReference Include="../../lib/Devices/Trumpf/TruConvert/TruConvert.csproj" />
|
<ProjectReference Include="../../lib/Devices/Trumpf/TruConvert/TruConvert.csproj" />
|
||||||
<ProjectReference Include="../../lib/StatusApi/StatusApi.csproj" />
|
<ProjectReference Include="../../lib/StatusApi/StatusApi.csproj" />
|
||||||
<ProjectReference Include="../../lib/Utils/Utils.csproj" />
|
<ProjectReference Include="../../lib/Utils/Utils.csproj" />
|
||||||
<PackageReference Include="CliWrap" Version="3.5.0" />
|
<PackageReference Include="CliWrap" Version="3.6.0" />
|
||||||
<PackageReference Include="DecimalMath.DecimalEx" Version="1.0.2" />
|
<PackageReference Include="DecimalMath.DecimalEx" Version="1.0.2" />
|
||||||
<PackageReference Include="Flurl.Http" Version="3.2.4" />
|
<PackageReference Include="Flurl.Http" Version="3.2.4" />
|
||||||
<PackageReference Include="System.IO.Ports" Version="7.0.0" />
|
<PackageReference Include="System.IO.Ports" Version="7.0.0" />
|
||||||
<ProjectReference Include="..\..\lib\Time\Time.csproj" />
|
<ProjectReference Include="..\..\lib\Time\Time.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="src\StatusLog" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
dotnet_version='net6.0'
|
dotnet_version='net6.0'
|
||||||
|
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
echo -e "\n============================ Build ============================\n"
|
echo -e "\n============================ Build ============================\n"
|
||||||
|
@ -11,21 +10,28 @@ echo -e "\n============================ Build ============================\n"
|
||||||
dotnet publish \
|
dotnet publish \
|
||||||
./SaliMax.csproj \
|
./SaliMax.csproj \
|
||||||
-c Release \
|
-c Release \
|
||||||
-r linux-arm
|
-r linux-x64
|
||||||
|
|
||||||
echo -e "\n============================ Deploy ============================\n"
|
echo -e "\n============================ Deploy ============================\n"
|
||||||
|
|
||||||
rsync -v \
|
rsync -v \
|
||||||
./bin/Release/$dotnet_version/linux-arm/publish/* \
|
./bin/Release/$dotnet_version/linux-x64/publish/* \
|
||||||
debian@10.2.1.87:~/salimax
|
ie-entwicklung@10.2.3.49:~/salimax
|
||||||
|
|
||||||
echo -e "\n============================ Run ============================\n"
|
|
||||||
|
# debian@10.2.1.87:~/salimax
|
||||||
|
|
||||||
|
echo -e "\n============================ Restart Salimax sevice ============================\n"
|
||||||
|
|
||||||
ssh -tt \
|
ssh -tt \
|
||||||
-o StrictHostKeyChecking=no \
|
ie-entwicklung@10.2.3.49 \
|
||||||
-o UserKnownHostsFile=/dev/null \
|
sudo systemctl restart salimax.service
|
||||||
-o ConnectTimeout=2 \
|
|
||||||
debian@10.2.1.87 \
|
|
||||||
'~/salimax/SaliMax' \
|
echo -e "\n============================ Print service output ============================\n"
|
||||||
2>/dev/null
|
|
||||||
|
ssh -tt \
|
||||||
|
ie-entwicklung@10.2.3.49 \
|
||||||
|
journalctl -f -u salimax.service
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,14 +13,14 @@ public static class Control
|
||||||
public static Decimal ControlInverterPower(this StatusRecord status, Decimal targetInverterPower)
|
public static Decimal ControlInverterPower(this StatusRecord status, Decimal targetInverterPower)
|
||||||
{
|
{
|
||||||
var s = status.InverterStatus!;
|
var s = status.InverterStatus!;
|
||||||
var totalInverterAcPower = s.PowerAcL1 + s.PowerAcL2 + s.PowerAcL3;
|
var totalInverterAcPower = s.Ac.ActivePower;
|
||||||
|
|
||||||
return ControlPower(totalInverterAcPower, targetInverterPower,status.SalimaxConfig!.PConstant);
|
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)
|
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 LowerLimit(params Decimal[] deltas) => deltas.Max();
|
||||||
public static Decimal UpperLimit(params Decimal[] deltas) => deltas.Min();
|
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
|
// TODO: explain LowSOC curve
|
||||||
|
|
||||||
var a = -2 * s.SalimaxConfig!.SelfDischargePower / s.SalimaxConfig.HoldSocZone;
|
var a = -2 * s.SalimaxConfig!.SelfDischargePower / s.SalimaxConfig.HoldSocZone;
|
||||||
var b = -a * (s.SalimaxConfig.MinSoc + 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)
|
private static Decimal ControlPower(Decimal measurement, Decimal target, Decimal p)
|
||||||
|
|
|
@ -18,7 +18,7 @@ public static class Controller
|
||||||
|
|
||||||
private static readonly TimeSpan CommunicationTimeout = TimeSpan.FromSeconds(10);
|
private static readonly TimeSpan CommunicationTimeout = TimeSpan.FromSeconds(10);
|
||||||
|
|
||||||
private static readonly Int16 MaxmimumAllowedBatteryTemp = 315;
|
public static readonly Int16 MaxmimumAllowedBatteryTemp = 315;
|
||||||
|
|
||||||
private static UInt16 _numberOfInverters;
|
private static UInt16 _numberOfInverters;
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ public static class Controller
|
||||||
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
|
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
|
||||||
} => 9,
|
} => 9,
|
||||||
{
|
{
|
||||||
SaliMaxRelayStatus.K1: Open, SaliMaxRelayStatus.K2: Open, SaliMaxRelayStatus.K3: Closed,
|
SaliMaxRelayStatus.K1: Closed, SaliMaxRelayStatus.K2: Open, SaliMaxRelayStatus.K3: Open,
|
||||||
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
|
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
|
||||||
} => 10,
|
} => 10,
|
||||||
{
|
{
|
||||||
|
@ -79,11 +79,11 @@ public static class Controller
|
||||||
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
|
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
|
||||||
} => 11,
|
} => 11,
|
||||||
{
|
{
|
||||||
SaliMaxRelayStatus.K1: Open, SaliMaxRelayStatus.K2: Closed, SaliMaxRelayStatus.K3: Closed,
|
SaliMaxRelayStatus.K1: Closed, SaliMaxRelayStatus.K2: Closed, SaliMaxRelayStatus.K3: Open,
|
||||||
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
|
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
|
||||||
} => 12,
|
} => 12,
|
||||||
{
|
{
|
||||||
SaliMaxRelayStatus.K1: Closed, SaliMaxRelayStatus.K2: Open, SaliMaxRelayStatus.K3: Open,
|
SaliMaxRelayStatus.K1: Open, SaliMaxRelayStatus.K2: Open, SaliMaxRelayStatus.K3: Closed,
|
||||||
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
|
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
|
||||||
} => 13,
|
} => 13,
|
||||||
{
|
{
|
||||||
|
@ -91,7 +91,7 @@ public static class Controller
|
||||||
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
|
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
|
||||||
} => 14,
|
} => 14,
|
||||||
{
|
{
|
||||||
SaliMaxRelayStatus.K1: Closed, SaliMaxRelayStatus.K2: Closed, SaliMaxRelayStatus.K3: Open,
|
SaliMaxRelayStatus.K1: Open, SaliMaxRelayStatus.K2: Closed, SaliMaxRelayStatus.K3: Closed,
|
||||||
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
|
InverterStatus.AcDcActiveGridType: AcDcGridType.GridTied400V50Hz
|
||||||
} => 15,
|
} => 15,
|
||||||
{
|
{
|
||||||
|
@ -140,7 +140,10 @@ public static class Controller
|
||||||
|
|
||||||
public static ControlRecord SaliMaxControl(StatusRecord statusRecord)
|
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 resetDcAlarm = CheckDcDcAlarms(statusRecord);
|
||||||
|
|
||||||
var lastEocTime = GetLastEocTime(statusRecord);
|
var lastEocTime = GetLastEocTime(statusRecord);
|
||||||
|
@ -152,32 +155,48 @@ public static class Controller
|
||||||
var noGridMeter = statusRecord.GridMeterStatus == null;
|
var noGridMeter = statusRecord.GridMeterStatus == null;
|
||||||
var saliMaxConfig = statusRecord.SalimaxConfig with { LastEoc = lastEocTime };
|
var saliMaxConfig = statusRecord.SalimaxConfig with { LastEoc = lastEocTime };
|
||||||
|
|
||||||
var currentSaliMaxState = GetSaliMaxState(statusRecord);
|
|
||||||
ExplainState(currentSaliMaxState);
|
ExplainState(currentSaliMaxState);
|
||||||
|
|
||||||
const RelayState k2Relay = Closed;
|
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.BatteryStatus is not null; // this is to check
|
var dcPowerStageEnable = statusRecord.BatteriesStatus is not null; // TODO this is to check, Can be the batteries Status be null?
|
||||||
|
|
||||||
var salimaxRelay = statusRecord.SaliMaxRelayStatus! with { K2 = k2Relay }; // to check
|
var salimaxRelay = statusRecord.SaliMaxRelayStatus! with { K2 = k2Relay }; // to check // this is must be control
|
||||||
|
|
||||||
|
if (resetInverterAlarm)
|
||||||
if (statusRecord.BatteryStatus == null)
|
|
||||||
{
|
{
|
||||||
|
acPowerStageEnable = !resetInverterAlarm ;
|
||||||
|
acSlaveId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resetDcAlarm)
|
||||||
|
{
|
||||||
|
dcPowerStageEnable = !resetDcAlarm ;
|
||||||
|
}
|
||||||
|
|
||||||
|
acSlaveId.WriteLine(" AcSlave @");
|
||||||
|
|
||||||
|
if (statusRecord.BatteriesStatus == null)
|
||||||
|
{
|
||||||
|
Console.WriteLine(" No batteries");
|
||||||
return new ControlRecord
|
return new ControlRecord
|
||||||
{
|
{
|
||||||
AcControlRecord = Defaults.TruConvertAcControl with
|
AcControlRecord = Defaults.TruConvertAcControl with
|
||||||
{
|
{
|
||||||
SignedPowerNominalValue = 0,
|
SignedPowerNominalValue = 0,
|
||||||
PowerStageEnable = acPowerStageEnable,
|
PowerStageEnable = acPowerStageEnable,
|
||||||
|
CommunicationTimeout = CommunicationTimeout,
|
||||||
|
SlaveAddress = acSlaveId,
|
||||||
ResetsAlarmAndWarning = resetInverterAlarm
|
ResetsAlarmAndWarning = resetInverterAlarm
|
||||||
},
|
},
|
||||||
DcControlRecord = Defaults.TruConvertDcControl with
|
DcControlRecord = Defaults.TruConvertDcControl with
|
||||||
{
|
{
|
||||||
PowerStageEnable = dcPowerStageEnable,
|
PowerStageEnable = dcPowerStageEnable,
|
||||||
ResetsAlarmAndWarning = resetDcAlarm
|
ResetsAlarmAndWarning = resetDcAlarm,
|
||||||
|
TimeoutForCommunication = CommunicationTimeout
|
||||||
|
|
||||||
},
|
},
|
||||||
SalimaxConfig = saliMaxConfig, // must create a control of each
|
SalimaxConfig = saliMaxConfig, // must create a control of each
|
||||||
SalimaxRelays = salimaxRelay, // 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();
|
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 currentPowerSetPoint = statusRecord.InverterStatus!.AcSignedPowerValue;
|
||||||
|
|
||||||
var limitReason = "no limit";
|
var limitReason = "no limit";
|
||||||
|
@ -212,7 +263,7 @@ public static class Controller
|
||||||
goal = "Calibration Charge";
|
goal = "Calibration Charge";
|
||||||
delta = statusRecord.ControlInverterPower(statusRecord.SalimaxConfig.MaxInverterPower);
|
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})";
|
goal = $"reach min SOC (Min soc: {statusRecord.SalimaxConfig.MinSoc})";
|
||||||
delta = statusRecord.ControlInverterPower(statusRecord.SalimaxConfig
|
delta = statusRecord.ControlInverterPower(statusRecord.SalimaxConfig
|
||||||
|
@ -234,7 +285,7 @@ public static class Controller
|
||||||
delta = inverterAc2DcLimitPower;
|
delta = inverterAc2DcLimitPower;
|
||||||
}
|
}
|
||||||
|
|
||||||
var batteryChargingLimitPower = statusRecord.ControlBatteryPower(statusRecord.BatteryStatus!.MaxChargingPower);
|
var batteryChargingLimitPower = statusRecord.ControlBatteryPower(statusRecord.BatteriesStatus[0]!.MaxChargingPower);
|
||||||
|
|
||||||
if (delta > batteryChargingLimitPower)
|
if (delta > batteryChargingLimitPower)
|
||||||
{
|
{
|
||||||
|
@ -253,12 +304,12 @@ public static class Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
var batteryDischargingLimitPower =
|
var batteryDischargingLimitPower =
|
||||||
statusRecord.ControlBatteryPower(statusRecord.BatteryStatus!.MaxDischargingPower);
|
statusRecord.ControlBatteryPower(statusRecord.BatteriesStatus[0]!.MaxDischargingPower); // TODO change to avg battery
|
||||||
|
|
||||||
if (delta < batteryDischargingLimitPower)
|
if (delta < batteryDischargingLimitPower)
|
||||||
{
|
{
|
||||||
limitReason =
|
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;
|
delta = batteryDischargingLimitPower;
|
||||||
}
|
}
|
||||||
|
@ -271,13 +322,13 @@ public static class Controller
|
||||||
delta = keepMinSocLimitDelta;
|
delta = keepMinSocLimitDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if (statusRecord.BatteryStatus.BatteryTemperature >= 300) must not reduce the delta
|
// if (statusRecord.BatteriesStatus[0]!.Temperature >= 300) //must not reduce the delta
|
||||||
{
|
// {
|
||||||
var softLandingFactor = (MaxmimumAllowedBatteryTemp - statusRecord.BatteryStatus.BatteryTemperature) / 15; //starting softlanding from 300 degree
|
// var softLandingFactor = (MaxmimumAllowedBatteryTemp - statusRecord.BatteriesStatus[0]!.Temperature) / 15; //starting softlanding from 300 degree
|
||||||
limitReason =
|
// limitReason =
|
||||||
$"limiting discharging power in order to stay keep the battery temp below 315°: {statusRecord.BatteryStatus.BatteryTemperature}°" + " Softlanding factor: " + softLandingFactor;
|
// $"limiting discharging power in order to stay keep the battery temp below 315°: {statusRecord.BatteriesStatus[0]!.Temperature}°" + " Softlanding factor: " + softLandingFactor;
|
||||||
delta *= softLandingFactor;
|
// delta *= softLandingFactor;
|
||||||
}*/
|
// }
|
||||||
|
|
||||||
var newPowerSetPoint =
|
var newPowerSetPoint =
|
||||||
DistributePower(currentPowerSetPoint + delta, statusRecord.SalimaxConfig.MaxInverterPower);
|
DistributePower(currentPowerSetPoint + delta, statusRecord.SalimaxConfig.MaxInverterPower);
|
||||||
|
@ -289,32 +340,7 @@ public static class Controller
|
||||||
limitReason.WriteLine(" Limit reason");
|
limitReason.WriteLine(" Limit reason");
|
||||||
delta.WriteLine(" Delta");
|
delta.WriteLine(" Delta");
|
||||||
// "============".WriteLine();
|
// "============".WriteLine();
|
||||||
|
return newPowerSetPoint;
|
||||||
////////////////////////// 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
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static State TargetState(State currentState)
|
private static State TargetState(State currentState)
|
||||||
|
@ -423,7 +449,7 @@ public static class Controller
|
||||||
|
|
||||||
private static UnixTime GetLastEocTime(StatusRecord statusRecord)
|
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");
|
Console.WriteLine("battery has reached EOC");
|
||||||
File.AppendAllTextAsync(Config.LogSalimaxLog, String.Join(Environment.NewLine, UnixTime.Now + "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)
|
private static Boolean CheckDcDcAlarms(StatusRecord s)
|
||||||
{
|
{
|
||||||
|
s.DcDcStatus?.Alarms.Count.WriteLine(" Dc Alarm count");
|
||||||
if ( s.DcDcStatus?.Alarms.Count > 0 &&
|
if ( s.DcDcStatus?.Alarms.Count > 0 &&
|
||||||
s.DcDcStatus?.PowerOperation == false)
|
s.DcDcStatus?.PowerOperation == false)
|
||||||
{
|
{
|
||||||
|
@ -452,14 +479,15 @@ public static class Controller
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Boolean CheckInverterAlarms(StatusRecord s)
|
private static Boolean CheckInverterAlarms(StatusRecord s, UInt16 state)
|
||||||
{
|
{
|
||||||
if ( s.InverterStatus?.Alarms.Count > 0 &&
|
s.InverterStatus?.Alarms.Count.WriteLine(" Ac Alarm count");
|
||||||
s.InverterStatus?.PowerOperation == false)
|
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 true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,14 +5,26 @@ public enum State : Int16
|
||||||
{
|
{
|
||||||
State1 = 1,
|
State1 = 1,
|
||||||
State2 = 2,
|
State2 = 2,
|
||||||
|
State3 = 3,
|
||||||
State4 = 4,
|
State4 = 4,
|
||||||
|
State5 = 5,
|
||||||
State6 = 6,
|
State6 = 6,
|
||||||
|
State7 = 7,
|
||||||
|
State8 = 8,
|
||||||
State9 = 9,
|
State9 = 9,
|
||||||
|
State10 = 10,
|
||||||
|
State11 = 11,
|
||||||
State12 = 12,
|
State12 = 12,
|
||||||
State13 = 13,
|
State13 = 13,
|
||||||
|
State14 = 14,
|
||||||
State15 = 15,
|
State15 = 15,
|
||||||
State16 = 16,
|
State16 = 16,
|
||||||
State17 = 17,
|
State17 = 17,
|
||||||
|
State18 = 18,
|
||||||
|
State19 = 19,
|
||||||
|
State20 = 20,
|
||||||
State21 = 21,
|
State21 = 21,
|
||||||
State22 = 22,
|
State22 = 22,
|
||||||
|
State23 = 23,
|
||||||
|
State24 = 24
|
||||||
}
|
}
|
|
@ -3,5 +3,5 @@ namespace InnovEnergy.SaliMax.Controller;
|
||||||
|
|
||||||
public static class StateConfig
|
public static class StateConfig
|
||||||
{
|
{
|
||||||
public static readonly IReadOnlyList<Int32> AcPowerStageEnableStates = new[] { 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 };
|
public static readonly IReadOnlyList<Int32> AcPowerStageEnableStates = new[] {8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 };
|
||||||
}
|
}
|
|
@ -10,13 +10,13 @@ namespace InnovEnergy.SaliMax.Controller;
|
||||||
|
|
||||||
public record StatusRecord
|
public record StatusRecord
|
||||||
{
|
{
|
||||||
public TruConvertAcStatus? InverterStatus { get; init; }
|
public TruConvertAcStatus? InverterStatus { get; init; }
|
||||||
public TruConvertDcStatus? DcDcStatus { get; init; }
|
public TruConvertDcStatus? DcDcStatus { get; init; }
|
||||||
public Battery48TLStatus? BatteryStatus { get; init; }
|
public Battery48TLStatus[]? BatteriesStatus { get; set; } = Array.Empty<Battery48TLStatus>(); // TODO remove static
|
||||||
public EmuMeterStatus? GridMeterStatus { get; init; }
|
public AvgBatteriesStatus? AvgBatteriesStatus { get; init; }
|
||||||
public SaliMaxRelayStatus? SaliMaxRelayStatus { get; init; }
|
public EmuMeterStatus? GridMeterStatus { get; init; }
|
||||||
public AmptStatus? AmptStatus { get; init; }
|
public SaliMaxRelayStatus? SaliMaxRelayStatus { get; init; }
|
||||||
public EmuMeterStatus? AcInToAcOutMeterStatus { get; init; }
|
public AmptStatus? AmptStatus { get; init; }
|
||||||
public SalimaxConfig SalimaxConfig { get; init; } = null!;
|
public EmuMeterStatus? AcInToAcOutMeterStatus { get; init; }
|
||||||
|
public SalimaxConfig SalimaxConfig { get; init; } = null!;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,15 +11,16 @@ public static class Ampt
|
||||||
if (s is null)
|
if (s is null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
// TODO return one AMPT device to sum all the other
|
||||||
|
|
||||||
return DeviceType
|
return DeviceType
|
||||||
.PvOnDc
|
.PvOnDc
|
||||||
.CreateDevice("AMPT")
|
.CreateDevice("AMPT")
|
||||||
.AddProp("Current 1", s.Current1)
|
.AddProp("Current 1", s.Devices[0].Dc.Current)
|
||||||
.AddProp("Current 2", s.Current2)
|
.AddProp("Current 2", s.Devices[1].Dc.Current)
|
||||||
.AddProp("Voltage 1", s.Voltage1)
|
.AddProp("Voltage 1", s.Devices[0].Dc.Voltage)
|
||||||
.AddProp("Voltage 2", s.Voltage2)
|
.AddProp("Voltage 2", s.Devices[1].Dc.Voltage)
|
||||||
.AddProp("Power 1", s.Current1 * s.Voltage1)
|
.AddProp("Power 1", s.Devices[0].Dc.Current * s.Devices[0].Dc.Voltage)
|
||||||
.AddProp("Power 2", s.Current2 * s.Voltage2);
|
.AddProp("Power 2", s.Devices[1].Dc.Current * s.Devices[1].Dc.Voltage);
|
||||||
// .AddDcConnection(s.AvgCurrent.Round3(), s.AvgVolatge.Round3());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -14,13 +14,13 @@ public static class Battery48Tl
|
||||||
return DeviceType
|
return DeviceType
|
||||||
.Battery
|
.Battery
|
||||||
.CreateDevice("48TL Battery")
|
.CreateDevice("48TL Battery")
|
||||||
.AddDc48Connection(s.Current.Round3(),s.Voltage.Round3())
|
.AddDc48Connection(s.Dc.Current.Round3(),s.Dc.Voltage.Round3())
|
||||||
.AddAlarms(s.Alarms)
|
.AddAlarms(s.Alarms)
|
||||||
.AddWarnings(s.Warnings)
|
.AddWarnings(s.Warnings)
|
||||||
.AddProp("Soc", s.Soc.Round3())
|
.AddProp("Soc", s.Soc.Round3())
|
||||||
.AddProp("HeaterOn", s.HeaterOn)
|
.AddProp("HeaterOn", s.HeaterOn)
|
||||||
.AddProp("EocReached", s.EocReached)
|
.AddProp("EocReached", s.EocReached)
|
||||||
.AddProp("BatteryCold", s.BatteryCold)
|
.AddProp("BatteryCold", s.BatteryCold)
|
||||||
.AddProp("Temperature", s.BatteryTemperature);
|
.AddProp("Temperature", s.Temperature);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -17,16 +17,16 @@ public static class EmuMeter
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
var l1 = CreateAcPhase(s.CurrentL1, s.VoltageL1N, ACos(s.PowerFactorL1));
|
var l1 = CreateAcPhase(s.Ac.L1.Current, s.Ac.L1.Voltage, ACos(s.Ac.L1.PowerFactor));
|
||||||
var l2 = CreateAcPhase(s.CurrentL2, s.VoltageL2N, ACos(s.PowerFactorL2));
|
var l2 = CreateAcPhase(s.Ac.L2.Current, s.Ac.L2.Voltage, ACos(s.Ac.L2.PowerFactor));
|
||||||
var l3 = CreateAcPhase(s.CurrentL3, s.VoltageL3N, ACos(s.PowerFactorL3));
|
var l3 = CreateAcPhase(s.Ac.L3.Current, s.Ac.L3.Voltage, ACos(s.Ac.L3.PowerFactor));
|
||||||
|
|
||||||
var ac = new JsonObject
|
var ac = new JsonObject
|
||||||
{
|
{
|
||||||
["L1"] = l1,
|
["L1"] = l1,
|
||||||
["L2"] = l2,
|
["L2"] = l2,
|
||||||
["L3"] = l3,
|
["L3"] = l3,
|
||||||
["Frequency"] = s.Frequency
|
["Frequency"] = s.Ac.Frequency
|
||||||
};
|
};
|
||||||
|
|
||||||
var status = new JsonObject
|
var status = new JsonObject
|
||||||
|
@ -39,8 +39,8 @@ public static class EmuMeter
|
||||||
|
|
||||||
private static IEnumerable<JsonObject> GetAcPhases(this EmuMeterStatus s)
|
private static IEnumerable<JsonObject> GetAcPhases(this EmuMeterStatus s)
|
||||||
{
|
{
|
||||||
yield return CreateAcPhase(s.CurrentL1.Round3(),s.VoltageL1N.Round3(),s.PowerFactorL1.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.CurrentL2.Round3(),s.VoltageL2N.Round3(),s.PowerFactorL2.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.CurrentL3.Round3(),s.VoltageL3N.Round3(),s.PowerFactorL3.Apply(ACos).Round3());
|
yield return CreateAcPhase(s.Ac.L3.Current.Round3(),s.Ac.L3.Voltage.Round3(),s.Ac.L3.PowerFactor.Apply(ACos).Round3());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -24,15 +24,16 @@ public static class Salimax
|
||||||
|
|
||||||
private static IEnumerable<JsonNode?> GetDevices(StatusRecord s)
|
private static IEnumerable<JsonNode?> GetDevices(StatusRecord s)
|
||||||
{
|
{
|
||||||
yield return s.InverterStatus.Log("1234");
|
yield return s.InverterStatus.Log();
|
||||||
yield return s.DcDcStatus.Log("3214");
|
yield return s.DcDcStatus.Log("3214");
|
||||||
yield return s.GridMeterStatus.Log(DeviceType.Grid);
|
yield return s.GridMeterStatus.Log(DeviceType.Grid , "123");
|
||||||
yield return s.AcInToAcOutMeterStatus.Log(DeviceType.AcInToAcOut);
|
yield return s.AcInToAcOutMeterStatus.Log(DeviceType.AcInToAcOut, "123");
|
||||||
yield return s.AmptStatus.Log();
|
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
|
var acInBusJson = JsonUtil.CreateBus
|
||||||
(
|
(
|
||||||
|
|
|
@ -9,13 +9,12 @@ namespace InnovEnergy.SaliMax.Log;
|
||||||
public static class TruConvertAc
|
public static class TruConvertAc
|
||||||
{
|
{
|
||||||
|
|
||||||
// TODO: remove serialNb arg, embed TruConvertDcStatus
|
public static JsonObject? Log(this TruConvertAcStatus? s)
|
||||||
public static JsonObject? Log(this TruConvertAcStatus? s, String serialNb)
|
|
||||||
{
|
{
|
||||||
if (s is null)
|
if (s is null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var dcPower = s.PowerAcL1 + s.PowerAcL2 + s.PowerAcL3;
|
var dcPower = s.Ac.ActivePower;
|
||||||
var dcVoltage = s.ActualDcLinkVoltageLowerHalfExt + s.ActualDcLinkVoltageUpperHalfExt;
|
var dcVoltage = s.ActualDcLinkVoltageLowerHalfExt + s.ActualDcLinkVoltageUpperHalfExt;
|
||||||
var dcCurrent = dcVoltage != 0m
|
var dcCurrent = dcVoltage != 0m
|
||||||
? dcPower / dcVoltage
|
? dcPower / dcVoltage
|
||||||
|
@ -25,16 +24,16 @@ public static class TruConvertAc
|
||||||
// TODO: acos quadrant
|
// TODO: acos quadrant
|
||||||
// TODO: total AC power
|
// TODO: total AC power
|
||||||
|
|
||||||
var l1 = CreateAcPhase(s.PhaseCurrentL1, s.GridVoltageL1, ACos(s.CosPhiL1));
|
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.PhaseCurrentL2, s.GridVoltageL2, ACos(s.CosPhiL2));
|
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.PhaseCurrentL3, s.GridVoltageL3, ACos(s.CosPhiL3));
|
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
|
var ac = new JsonObject
|
||||||
{
|
{
|
||||||
["L1"] = l1,
|
["L1"] = l1,
|
||||||
["L2"] = l2,
|
["L2"] = l2,
|
||||||
["L3"] = l3,
|
["L3"] = l3,
|
||||||
["Frequency"] = s.GridFrequency
|
["Frequency"] = s.Ac.Frequency
|
||||||
};
|
};
|
||||||
|
|
||||||
var dc = CreateDcPhase(dcCurrent, dcVoltage);
|
var dc = CreateDcPhase(dcCurrent, dcVoltage);
|
||||||
|
@ -47,20 +46,20 @@ public static class TruConvertAc
|
||||||
["Alarms"] = s.Alarms.ToJsonArray() ,
|
["Alarms"] = s.Alarms.ToJsonArray() ,
|
||||||
};
|
};
|
||||||
|
|
||||||
return new JsonObject { [$"TruConvertAc {serialNb}"] = status };
|
return new JsonObject { [$"TruConvertAc {s.SerialNumber}"] = status };
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IEnumerable<JsonObject> GetAcPhases(this TruConvertAcStatus s)
|
private static IEnumerable<JsonObject> GetAcPhases(this TruConvertAcStatus s)
|
||||||
{
|
{
|
||||||
// Math.Acos return "NaN" if the cos phi < -1 or > 1
|
// Math.Acos return "NaN" if the cos phi < -1 or > 1
|
||||||
// Decimal.Acos throw an exception
|
// Decimal.Acos throw an exception
|
||||||
yield return JsonUtil.CreateAcPhase(s.PhaseCurrentL1.Round3(), s.GridVoltageL1.Round3(),
|
yield return JsonUtil.CreateAcPhase(s.Ac.L1.Current.Round3(), s.Ac.L1.Voltage.Round3(),
|
||||||
s.CosPhiL1.Clamp(-1m, 1m).Apply(ACos).Round3());
|
s.Ac.L1.PowerFactor.Clamp(-1m, 1m).Apply(ACos).Round3());
|
||||||
|
|
||||||
yield return JsonUtil.CreateAcPhase(s.PhaseCurrentL2.Round3(), s.GridVoltageL2.Round3(),
|
yield return JsonUtil.CreateAcPhase(s.Ac.L2.Current.Round3(), s.Ac.L2.Voltage.Round3(),
|
||||||
s.CosPhiL2.Clamp(-1m, 1m).Apply(ACos).Round3());
|
s.Ac.L2.PowerFactor.Clamp(-1m, 1m).Apply(ACos).Round3());
|
||||||
|
|
||||||
yield return JsonUtil.CreateAcPhase(s.PhaseCurrentL3.Round3(), s.GridVoltageL3.Round3(),
|
yield return JsonUtil.CreateAcPhase(s.Ac.L3.Current.Round3(), s.Ac.L3.Voltage.Round3(),
|
||||||
s.CosPhiL3.Clamp(-1m, 1m).Apply(ACos).Round3());
|
s.Ac.L3.PowerFactor.Clamp(-1m, 1m).Apply(ACos).Round3());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -14,30 +14,19 @@ public static class TruConvertDc
|
||||||
if (s is null)
|
if (s is null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var dcCurrent = s.DcLinkVoltage != 0m
|
var dcCurrent = s.Dc.Current;
|
||||||
? s.DcPower / s.DcLinkVoltage
|
|
||||||
: 0m;
|
|
||||||
|
|
||||||
return new JO
|
return new JO
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
$"TruConvertDc {serialNb}", new JO
|
$"TruConvertDc {serialNb}", new JO
|
||||||
{
|
{
|
||||||
{ "Dc" , CreateDcPhase(dcCurrent, s.DcLinkVoltage) },
|
{ "Dc" , CreateDcPhase(dcCurrent, s.Dc.Voltage) },
|
||||||
{ "Dc48" , CreateDcPhase(s.BatteryCurrent, s.BatteryVoltage) },
|
{ "Dc48" , CreateDcPhase(s.BatteryCurrent, s.BatteryVoltage) },
|
||||||
{ "Warnings", s.Warnings.ToJsonArray() },
|
{ "Warnings", s.Warnings.ToJsonArray() },
|
||||||
{ "Alarms" , s.Alarms.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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,3 +1,6 @@
|
||||||
|
#undef BatteriesAllowed
|
||||||
|
|
||||||
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Nodes;
|
using System.Text.Json.Nodes;
|
||||||
|
@ -14,9 +17,12 @@ using InnovEnergy.SaliMax.Log;
|
||||||
using InnovEnergy.SaliMax.SaliMaxRelays;
|
using InnovEnergy.SaliMax.SaliMaxRelays;
|
||||||
using InnovEnergy.SaliMax.SystemConfig;
|
using InnovEnergy.SaliMax.SystemConfig;
|
||||||
using InnovEnergy.Time.Unix;
|
using InnovEnergy.Time.Unix;
|
||||||
|
using Utils = InnovEnergy.Lib.StatusApi.Utils;
|
||||||
|
|
||||||
|
|
||||||
#pragma warning disable IL2026
|
#pragma warning disable IL2026
|
||||||
|
|
||||||
|
|
||||||
namespace InnovEnergy.SaliMax;
|
namespace InnovEnergy.SaliMax;
|
||||||
|
|
||||||
internal static class Program
|
internal static class Program
|
||||||
|
@ -31,7 +37,8 @@ internal static class Program
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
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;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,33 +58,58 @@ internal static class Program
|
||||||
};
|
};
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
var inverterDevice = new TruConvertAcDevice("127.0.0.1", 5001);
|
var inverterDevice = new TruConvertAcDevice("127.0.0.1", 5001);
|
||||||
var dcDcDevice = new TruConvertDcDevice("127.0.0.1", 5002);
|
var dcDcDevice = new TruConvertDcDevice("127.0.0.1", 5002);
|
||||||
var gridMeterDevice = new EmuMeterDevice("127.0.0.1", 5003);
|
var gridMeterDevice = new EmuMeterDevice("127.0.0.1", 5003);
|
||||||
var saliMaxRelaysDevice = new SaliMaxRelaysDevice("127.0.0.1", 5004);
|
var saliMaxRelaysDevice = new SaliMaxRelaysDevice("127.0.0.1", 5004);
|
||||||
var amptDevice = new AmptCommunicationUnit("127.0.0.1", 5005);
|
var amptDevice = new AmptCommunicationUnit("127.0.0.1", 5005);
|
||||||
var acInToAcOutMeterDevice = new EmuMeterDevice("127.0.0.1", 5003); // TODO: use real device
|
var acInToAcOutMeterDevice = new EmuMeterDevice("127.0.0.1", 5003); // TODO: use real device
|
||||||
var battery48TlDevice = Battery48TlDevice.Fake();
|
var secondBattery48TlDevice = Battery48TlDevice.Fake();
|
||||||
var salimaxConfig = new SalimaxConfig();
|
var firstBattery48TlDevice =Battery48TlDevice.Fake();;
|
||||||
#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 salimaxConfig = new SalimaxConfig();
|
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
|
#endif
|
||||||
|
|
||||||
|
var dcDcDevices = new[] { dcDcDevice };
|
||||||
|
var inverterDevices = new[] { inverterDevice};
|
||||||
|
|
||||||
StatusRecord ReadStatus()
|
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
|
return new StatusRecord
|
||||||
{
|
{
|
||||||
InverterStatus = inverterDevice.ReadStatus(),
|
InverterStatus = inverterDevice.ReadStatus(),
|
||||||
DcDcStatus = dcDcDevice.ReadStatus(),
|
DcDcStatus = dcDcDevice.ReadStatus(),
|
||||||
BatteryStatus = battery48TlDevice.ReadStatus(),
|
#if BatteriesAllowed
|
||||||
|
|
||||||
|
BatteriesStatus = battery48TlStatusArray,
|
||||||
|
AvgBatteriesStatus = AvgBatteriesStatus.ReadBatteriesStatus(battery48TlStatusArray),
|
||||||
|
#else
|
||||||
|
BatteriesStatus = null,
|
||||||
|
AvgBatteriesStatus = null,
|
||||||
|
#endif
|
||||||
AcInToAcOutMeterStatus = acInToAcOutMeterDevice.ReadStatus(),
|
AcInToAcOutMeterStatus = acInToAcOutMeterDevice.ReadStatus(),
|
||||||
GridMeterStatus = gridMeterDevice.ReadStatus(),
|
GridMeterStatus = gridMeterDevice.ReadStatus(),
|
||||||
SaliMaxRelayStatus = saliMaxRelaysDevice.ReadStatus(),
|
SaliMaxRelayStatus = saliMaxRelaysDevice.ReadStatus(),
|
||||||
|
@ -87,10 +119,11 @@ internal static class Program
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var startTime = UnixTime.Now;
|
var startTime = UnixTime.Now;
|
||||||
const Int32 delayTime = 10;
|
const Int32 delayTime = 10;
|
||||||
|
|
||||||
ReleaseWriteTopology(startTime);
|
|
||||||
|
await UploadTopology(s3Config, Salimax.TopologyToLog(startTime), startTime);
|
||||||
DebugWriteTopology(startTime);
|
DebugWriteTopology(startTime);
|
||||||
|
|
||||||
Console.WriteLine("press ctrl-C to stop");
|
Console.WriteLine("press ctrl-C to stop");
|
||||||
|
@ -104,16 +137,17 @@ internal static class Program
|
||||||
await Task.Delay(delayTime);
|
await Task.Delay(delayTime);
|
||||||
t = UnixTime.Now;
|
t = UnixTime.Now;
|
||||||
}
|
}
|
||||||
var status = ReadStatus();
|
|
||||||
//var jsonLog = status.ToLog(t);
|
|
||||||
|
|
||||||
//await UploadTimeSeries(s3Config, jsonLog, t);
|
var status = ReadStatus();
|
||||||
|
#if BatteriesAllowed
|
||||||
|
|
||||||
|
var jsonLog = status.ToLog(t);
|
||||||
|
await UploadTimeSeries(s3Config, jsonLog, t);
|
||||||
var controlRecord = Controller.Controller.SaliMaxControl(status);
|
var controlRecord = Controller.Controller.SaliMaxControl(status);
|
||||||
Controller.Controller.WriteControlRecord(controlRecord, inverterDevice, dcDcDevice, saliMaxRelaysDevice);
|
Controller.Controller.WriteControlRecord(controlRecord, inverterDevice, dcDcDevice, saliMaxRelaysDevice);
|
||||||
|
|
||||||
// JsonSerializer.Serialize(jsonLog, JsonOptions).WriteLine(ConsoleColor.DarkBlue);
|
//JsonSerializer.Serialize(jsonLog, JsonOptions).WriteLine(ConsoleColor.DarkBlue);
|
||||||
|
#endif
|
||||||
//ReleaseWriteLog(jsonLog, t);
|
|
||||||
PrintTopology(status);
|
PrintTopology(status);
|
||||||
|
|
||||||
while (UnixTime.Now == t)
|
while (UnixTime.Now == t)
|
||||||
|
@ -127,42 +161,41 @@ internal static class Program
|
||||||
{
|
{
|
||||||
const String chargingSeparator = ">>>>>>>>>>";
|
const String chargingSeparator = ">>>>>>>>>>";
|
||||||
const String dischargingSeparator = "<<<<<<<<<";
|
const String dischargingSeparator = "<<<<<<<<<";
|
||||||
const Int32 height = 25;
|
const Int32 height = 25;
|
||||||
|
|
||||||
|
|
||||||
var boxSize = chargingSeparator.Length / 2;
|
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 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 gridSeparator = s.GridMeterStatus!.ActivePowerL123 > 0 ? chargingSeparator : dischargingSeparator;
|
|
||||||
var inverterSeparator = -pwr > 0 ? chargingSeparator : dischargingSeparator;
|
var inverterSeparator = -pwr > 0 ? chargingSeparator : dischargingSeparator;
|
||||||
var dcSeparator = -s.DcDcStatus!.DcPower > 0 ? chargingSeparator : dischargingSeparator;
|
var dcSeparator = -s.DcDcStatus!.Dc.Power > 0 ? chargingSeparator : dischargingSeparator;
|
||||||
var batterySeparator = s.BatteryStatus!.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 //////////////////////
|
||||||
////////////////// Grid //////////////////////
|
var boxGrid = AsciiArt.CreateBox
|
||||||
var boxGrid = AsciiArt.CreateBox
|
|
||||||
(
|
(
|
||||||
"Grid",
|
"Grid",
|
||||||
s.GridMeterStatus.VoltageL1N.V(),
|
s.GridMeterStatus.Ac.L1.Voltage.V(),
|
||||||
s.GridMeterStatus.VoltageL2N.V(),
|
s.GridMeterStatus.Ac.L2.Voltage.V(),
|
||||||
s.GridMeterStatus.VoltageL3N.V()
|
s.GridMeterStatus.Ac.L3.Voltage.V()
|
||||||
).AlignCenterVertical(height);
|
).AlignCenterVertical(height);
|
||||||
|
|
||||||
//var gridBox = CreateRect(0, boxGrid).AlignBottom(height);
|
var gridAcBusArrow = AsciiArt.CreateHorizontalArrow(s.GridMeterStatus!.ActivePowerL123.Round0(), gridSeparator)
|
||||||
var gridAcBusArrow = AsciiArt.CreateHorizontalArrow(s.GridMeterStatus!.ActivePowerL123.Round0(), gridSeparator).AlignCenterVertical(height);
|
.AlignCenterVertical(height);
|
||||||
|
|
||||||
|
|
||||||
////////////////// Ac Bus //////////////////////
|
////////////////// Ac Bus //////////////////////
|
||||||
var boxAcBus = AsciiArt.CreateBox
|
var boxAcBus = AsciiArt.CreateBox
|
||||||
(
|
(
|
||||||
"AC Bus",
|
"AC Bus",
|
||||||
s.InverterStatus.GridVoltageL1.V(),
|
s.InverterStatus.Ac.L1.Voltage.V(),
|
||||||
s.InverterStatus.GridVoltageL2.V(),
|
s.InverterStatus.Ac.L2.Voltage.V(),
|
||||||
s.InverterStatus.GridVoltageL3.V()
|
s.InverterStatus.Ac.L3.Voltage.V()
|
||||||
);
|
);
|
||||||
|
|
||||||
var boxLoad = AsciiArt.CreateBox
|
var boxLoad = AsciiArt.CreateBox
|
||||||
|
@ -172,107 +205,147 @@ internal static class Program
|
||||||
""
|
""
|
||||||
);
|
);
|
||||||
|
|
||||||
var loadRect = CreateRect(loadPower, boxAcBus, boxLoad).AlignBottom(height);
|
var loadRect = CreateRect(boxAcBus, boxLoad, loadPower).AlignBottom(height);
|
||||||
|
|
||||||
var acBusInvertArrow = AsciiArt.CreateHorizontalArrow(-pwr.Round0(), inverterSeparator).AlignCenterVertical(height);
|
var acBusInvertArrow = AsciiArt.CreateHorizontalArrow(-pwr.Round0(), inverterSeparator)
|
||||||
|
.AlignCenterVertical(height);
|
||||||
|
|
||||||
//////////////////// Inverter /////////////////////////
|
//////////////////// Inverter /////////////////////////
|
||||||
var inverterBox = AsciiArt.CreateBox
|
var inverterBox = AsciiArt.CreateBox
|
||||||
(
|
(
|
||||||
"",
|
"",
|
||||||
"Inverter",
|
"Inverter",
|
||||||
""
|
""
|
||||||
).AlignCenterVertical(height);
|
).AlignCenterVertical(height);
|
||||||
|
|
||||||
var inverterArrow = AsciiArt.CreateHorizontalArrow(-pwr.Round0(), inverterSeparator).AlignCenterVertical(height);
|
var inverterArrow = AsciiArt.CreateHorizontalArrow(-pwr.Round0(), inverterSeparator)
|
||||||
|
.AlignCenterVertical(height);
|
||||||
|
|
||||||
|
|
||||||
//////////////////// DC Bus /////////////////////////
|
//////////////////// DC Bus /////////////////////////
|
||||||
var dcBusBox = AsciiArt.CreateBox
|
var dcBusBox = AsciiArt.CreateBox
|
||||||
(
|
(
|
||||||
"DC Bus",
|
"DC Bus",
|
||||||
(s.InverterStatus.ActualDcLinkVoltageLowerHalfExt + s.InverterStatus.ActualDcLinkVoltageUpperHalfExt).V(),
|
(s.InverterStatus.ActualDcLinkVoltageLowerHalfExt + s.InverterStatus.ActualDcLinkVoltageUpperHalfExt).V(),
|
||||||
""
|
""
|
||||||
);
|
);
|
||||||
|
|
||||||
var pvBox = AsciiArt.CreateBox
|
var pvBox = AsciiArt.CreateBox
|
||||||
(
|
(
|
||||||
"",
|
"MPPT",
|
||||||
"MPPT",
|
((s.AmptStatus!.Devices[0].Dc.Voltage + s.AmptStatus!.Devices[1].Dc.Voltage) / 2).Round0().V(),
|
||||||
""
|
""
|
||||||
);
|
);
|
||||||
|
|
||||||
var pvRect = CreateRect(pvPower, pvBox, dcBusBox).AlignTop(height);
|
var pvRect = CreateRect(pvBox, dcBusBox, pvPower).AlignTop(height);
|
||||||
|
|
||||||
var dcBusArrow = AsciiArt.CreateHorizontalArrow(-s.DcDcStatus!.DcPower.Round0(), dcSeparator).AlignCenterVertical(height);
|
var dcBusArrow = AsciiArt.CreateHorizontalArrow(-s.DcDcStatus!.Dc.Power, dcSeparator)
|
||||||
|
.AlignCenterVertical(height);
|
||||||
|
|
||||||
//////////////////// Dc/Dc /////////////////////////
|
//////////////////// Dc/Dc /////////////////////////
|
||||||
var dcBox = AsciiArt.CreateBox
|
var dcBox = AsciiArt.CreateBox
|
||||||
(
|
(
|
||||||
"",
|
"Dc/Dc",
|
||||||
"Dc/Dc",
|
s.DcDcStatus.BatteryVoltage.V(),
|
||||||
""
|
""
|
||||||
).AlignCenterVertical(height);
|
).AlignCenterVertical(height);
|
||||||
|
#if BatteriesAllowed
|
||||||
var dcArrow = AsciiArt.CreateHorizontalArrow(s.BatteryStatus!.Power.Round0(), batterySeparator).AlignCenterVertical(height);
|
var dcArrow1 = AsciiArt.CreateHorizontalArrow(s.BatteriesStatus[0]!.Power.Round0(), battery1Separator);
|
||||||
|
var dcArrow2 = AsciiArt.CreateHorizontalArrow(s.BatteriesStatus[1]!.Power.Round0(), battery2Separator);
|
||||||
//////////////////// Battery /////////////////////////
|
#else
|
||||||
var batteryBox = AsciiArt.CreateBox
|
var dcArrow1 ="";
|
||||||
(
|
var dcArrow2 = "";
|
||||||
"Battery",
|
var dcArrowRect = CreateRect(dcArrow1, dcArrow2).AlignCenterVertical(height);
|
||||||
s.BatteryStatus!.Voltage.V(),
|
#endif
|
||||||
""
|
|
||||||
).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");
|
|
||||||
|
|
||||||
|
|
||||||
var topology = boxGrid.SideBySideWith(gridAcBusArrow,"")
|
#if BatteriesAllowed
|
||||||
.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;
|
//////////////////// 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(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 powerArrow = AsciiArt.CreateVerticalArrow(power);
|
||||||
var boxes = new[] { boxAcBus, loadAcBusArrow, boxLoad };
|
var boxes = new[] { boxTop, powerArrow, boxBottom };
|
||||||
var maxWidth = boxes.Max(l => l.Width());
|
var maxWidth = boxes.Max(l => l.Width());
|
||||||
|
|
||||||
var rect = boxes.Select(l => l.AlignCenterHorizontal(maxWidth)).JoinLines();
|
var rect = boxes.Select(l => l.AlignCenterHorizontal(maxWidth)).JoinLines();
|
||||||
return rect;
|
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")]
|
[Conditional("RELEASE")]
|
||||||
private static void ReleaseWriteLog(JsonObject jsonLog, UnixTime timestamp)
|
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")]
|
// [Conditional("RELEASE")]
|
||||||
private static void ReleaseWriteTopology(UnixTime timestamp)
|
private static JsonObject ReleaseWriteTopology(UnixTime timestamp)
|
||||||
{
|
{
|
||||||
var topologyJson = Salimax.TopologyToLog(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")]
|
[Conditional("DEBUG")]
|
||||||
|
@ -318,4 +391,19 @@ internal static class Program
|
||||||
Console.WriteLine(error);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -2,9 +2,6 @@ namespace InnovEnergy.SaliMax.SaliMaxRelays;
|
||||||
|
|
||||||
public record SaliMaxRelayStatus
|
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 K1 { get; init; } = RelayState.Closed; // Address on Adam(0X) 00002
|
||||||
public RelayState K2 { get; init; } = RelayState.Closed; // Address on Adam(0X) 00003
|
public RelayState K2 { get; init; } = RelayState.Closed; // Address on Adam(0X) 00003
|
||||||
public RelayState K3 { get; init; } = RelayState.Closed; // Address on Adam(0X) 00004
|
public RelayState K3 { get; init; } = RelayState.Closed; // Address on Adam(0X) 00004
|
||||||
|
|
|
@ -2,5 +2,5 @@ namespace InnovEnergy.SaliMax.SystemConfig;
|
||||||
|
|
||||||
public static class Config
|
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
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@ public static class Defaults
|
||||||
Subnet = default, //= 0x FFFFFF00;
|
Subnet = default, //= 0x FFFFFF00;
|
||||||
Gateway = default, //= 0x C0A80102;
|
Gateway = default, //= 0x C0A80102;
|
||||||
ResetParamToDefault = false, // Coil
|
ResetParamToDefault = false, // Coil
|
||||||
CommunicationTimeout = default,
|
CommunicationTimeout = TimeSpan.FromSeconds(10),
|
||||||
FactoryResetParameters = false,
|
FactoryResetParameters = false,
|
||||||
ConnectedSystemConfig = Lib.Devices.Trumpf.TruConvert.SystemConfig.AcDcAndDcDc,
|
ConnectedSystemConfig = Lib.Devices.Trumpf.TruConvert.SystemConfig.AcDcAndDcDc,
|
||||||
UpdateSwTrigger = 0,
|
UpdateSwTrigger = 0,
|
||||||
|
@ -25,7 +25,7 @@ public static class Defaults
|
||||||
// IlBuildnumber = 0,
|
// IlBuildnumber = 0,
|
||||||
PowerStageEnable = true,
|
PowerStageEnable = true,
|
||||||
SetValueConfig = SymmetricAcOperationMode.Symmetric, // Asymmetric = 0, // this is can not be seen in UI
|
SetValueConfig = SymmetricAcOperationMode.Symmetric, // Asymmetric = 0, // this is can not be seen in UI
|
||||||
ResetsAlarmAndWarning = false,
|
ResetsAlarmAndWarning = true,
|
||||||
PreChargeDcLinkConfig = PreChargeDcLinkConfig.Internal, // 1 = internal
|
PreChargeDcLinkConfig = PreChargeDcLinkConfig.Internal, // 1 = internal
|
||||||
PowerFactorConvention = PowerFactorConvention.Producer, // 0 = producer
|
PowerFactorConvention = PowerFactorConvention.Producer, // 0 = producer
|
||||||
SlaveAddress = 1,
|
SlaveAddress = 1,
|
||||||
|
@ -66,9 +66,9 @@ public static class Defaults
|
||||||
GridFormingMode = 0, // 0 = not grid-forming (grid-tied) ,1 = grid-forming TODO enum
|
GridFormingMode = 0, // 0 = not grid-forming (grid-tied) ,1 = grid-forming TODO enum
|
||||||
|
|
||||||
//remove DC stuff from AC
|
//remove DC stuff from AC
|
||||||
DcLinkRefVoltage = 850,
|
DcLinkRefVoltage = 800,
|
||||||
DcLinkMinVoltage = 830,
|
DcLinkMinVoltage = 780,
|
||||||
DcLinkMaxVoltage = 870,
|
DcLinkMaxVoltage = 820,
|
||||||
DcVoltageRefUs = 900,
|
DcVoltageRefUs = 900,
|
||||||
DcMinVoltageUs = 880,
|
DcMinVoltageUs = 880,
|
||||||
DcMaxVoltageUs = 920,
|
DcMaxVoltageUs = 920,
|
||||||
|
@ -88,7 +88,7 @@ public static class Defaults
|
||||||
Subnet = default,
|
Subnet = default,
|
||||||
Gateway = default,
|
Gateway = default,
|
||||||
ResetParamToDefault = false ,
|
ResetParamToDefault = false ,
|
||||||
TimeoutForCommunication = default ,
|
TimeoutForCommunication = TimeSpan.FromSeconds(10) ,
|
||||||
RestartFlag = false ,
|
RestartFlag = false ,
|
||||||
ConnectedSystemConfig = Lib.Devices.Trumpf.TruConvert.SystemConfig.DcDcOnly,
|
ConnectedSystemConfig = Lib.Devices.Trumpf.TruConvert.SystemConfig.DcDcOnly,
|
||||||
UpdateSwTrigger = 0,
|
UpdateSwTrigger = 0,
|
||||||
|
@ -98,7 +98,7 @@ public static class Defaults
|
||||||
SerialNumberDcDc = 0,
|
SerialNumberDcDc = 0,
|
||||||
MaterialNumberDcDc = 0,
|
MaterialNumberDcDc = 0,
|
||||||
PowerStageEnable = true,
|
PowerStageEnable = true,
|
||||||
ResetsAlarmAndWarning = false,
|
ResetsAlarmAndWarning = false,
|
||||||
SlaveAddress = 1,
|
SlaveAddress = 1,
|
||||||
SubSlaveAddress = 0,
|
SubSlaveAddress = 0,
|
||||||
ModbusSlaveId = false,
|
ModbusSlaveId = false,
|
||||||
|
@ -112,7 +112,7 @@ public static class Defaults
|
||||||
BatteryCurrentSet = 0,
|
BatteryCurrentSet = 0,
|
||||||
DynamicCurrentPerMillisecond = 2,
|
DynamicCurrentPerMillisecond = 2,
|
||||||
DcLinkControlMode = 1,
|
DcLinkControlMode = 1,
|
||||||
ReferenceVoltage = 850,
|
ReferenceVoltage = 800,
|
||||||
UpperVoltageWindow = 40,
|
UpperVoltageWindow = 40,
|
||||||
LowerVoltageWindow = 40,
|
LowerVoltageWindow = 40,
|
||||||
VoltageDeadBand = 0,
|
VoltageDeadBand = 0,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using DecimalMath;
|
using DecimalMath;
|
||||||
using InnovEnergy.Lib.Protocols.Modbus.Clients;
|
using InnovEnergy.Lib.Protocols.Modbus.Clients;
|
||||||
using InnovEnergy.Lib.Protocols.Modbus.Connections;
|
using InnovEnergy.Lib.Protocols.Modbus.Connections;
|
||||||
|
using InnovEnergy.Lib.StatusApi.Connections;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Devices.Ampt;
|
namespace InnovEnergy.Lib.Devices.Ampt;
|
||||||
|
|
||||||
|
@ -48,25 +49,22 @@ public class AmptCommunicationUnit
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var amptSt = new AmptStatus
|
var amptSt = new AmptStatus
|
||||||
{
|
(
|
||||||
Sid = r.GetUInt32(1),
|
Sid : r.GetUInt32(1),
|
||||||
IdSunSpec = r.GetUInt16(3),
|
IdSunSpec : r.GetUInt16(3),
|
||||||
Manufacturer = r.GetString(5, 16),
|
Manufacturer : r.GetString(5, 16),
|
||||||
Model = r.GetString(21, 16),
|
Model : r.GetString(21, 16),
|
||||||
Version = r.GetString(45, 8),
|
Version : r.GetString(45, 8),
|
||||||
SerialNumber = r.GetString(53, 16),
|
SerialNumber : r.GetString(53, 16),
|
||||||
DeviceAddress = r.GetInt16(69),
|
DeviceAddress : r.GetInt16(69),
|
||||||
IdVendor = r.GetUInt16(71),
|
IdVendor : r.GetUInt16(71),
|
||||||
Devices = devices,
|
Devices : devices
|
||||||
Current1 = r.GetInt16(90) * currentFactor,
|
// devices.d Current1 = r.GetInt16(90) * currentFactor,
|
||||||
Current2 = r.GetInt16(106) * currentFactor,
|
// Current2 = r.GetInt16(106) * currentFactor,
|
||||||
Voltage1 = r.GetUInt32(91) * voltageFactor,
|
// Voltage1 = r.GetUInt32(91) * voltageFactor,
|
||||||
Voltage2 = r.GetUInt32(107) * voltageFactor,
|
// Voltage2 = r.GetUInt32(107) * voltageFactor
|
||||||
|
|
||||||
//AvgVolatge = ReadDevicesVoltage(nbrOfDevices),
|
);
|
||||||
//AvgCurrent = ReadDevicesCurrent(nbrOfDevices)
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
return amptSt;
|
return amptSt;
|
||||||
|
@ -104,26 +102,30 @@ public class AmptCommunicationUnit
|
||||||
var b = (UInt16)(FirstDeviceOffset + deviceNumber * RegistersPerDevice); // base address
|
var b = (UInt16)(FirstDeviceOffset + deviceNumber * RegistersPerDevice); // base address
|
||||||
|
|
||||||
return new AmptDeviceStatus
|
return new AmptDeviceStatus
|
||||||
{
|
(
|
||||||
DeviceId = r.GetInt16 (b) ,
|
Dc : new DcConnection
|
||||||
Timestamp = r.GetUInt32((UInt16)(b + 3)),
|
(
|
||||||
Current = r.GetUInt16((UInt16)(b + 5)) * currentFactor,
|
Voltage:r.GetUInt32((UInt16)(b + 6)) * voltageFactor,
|
||||||
Voltage = r.GetUInt32((UInt16)(b + 6)) * voltageFactor,
|
Current:r.GetUInt16((UInt16)(b + 5)) * currentFactor
|
||||||
ProductionToday = r.GetUInt32((UInt16)(b + 12))* energyFactor,
|
),
|
||||||
Strings = new AmptStringStatus[]
|
DeviceId : r.GetInt16 (b) ,
|
||||||
|
Timestamp : r.GetUInt32((UInt16)(b + 3)),
|
||||||
|
ProductionToday : r.GetUInt32((UInt16)(b + 12))* energyFactor,
|
||||||
|
|
||||||
|
Strings : new []
|
||||||
{
|
{
|
||||||
new()
|
new DcConnection
|
||||||
{
|
(
|
||||||
Voltage = r.GetUInt32((UInt16)(b + 8)) * voltageFactor,
|
Voltage : r.GetUInt32((UInt16)(b + 8)) * voltageFactor,
|
||||||
Current = r.GetUInt16((UInt16)(b + 14)) * currentFactor,
|
Current : r.GetUInt16((UInt16)(b + 14)) * currentFactor
|
||||||
},
|
),
|
||||||
new()
|
new DcConnection
|
||||||
{
|
(
|
||||||
Voltage = r.GetUInt32((UInt16)(b + 9)) * voltageFactor,
|
Voltage : r.GetUInt32((UInt16)(b + 9)) * voltageFactor,
|
||||||
Current = r.GetUInt16((UInt16)(b + 15)) * currentFactor,
|
Current : r.GetUInt16((UInt16)(b + 15)) * currentFactor
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
};
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,14 +1,15 @@
|
||||||
|
using InnovEnergy.Lib.StatusApi.Connections;
|
||||||
|
using InnovEnergy.Lib.StatusApi.Devices;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Devices.Ampt;
|
namespace InnovEnergy.Lib.Devices.Ampt;
|
||||||
|
|
||||||
public record AmptDeviceStatus
|
public record AmptDeviceStatus
|
||||||
{
|
(
|
||||||
internal const UInt16 NbrOfStrings = 2;
|
DcConnection Dc,
|
||||||
public Int16 DeviceId { get; init; } // The string number
|
// UInt16 NbrOfStrings,
|
||||||
public UInt32 Timestamp { get; init; } // The UTC timestamp of the measurements
|
Int16 DeviceId, // The string number
|
||||||
|
UInt32 Timestamp, // The UTC timestamp of the measurements
|
||||||
public Decimal Current { get; init; } // String output current in mA
|
Decimal ProductionToday, // converted to kW in AmptCU class
|
||||||
public Decimal Voltage { get; init; } // String output voltage in mV
|
IReadOnlyList<DcConnection> Strings
|
||||||
|
): Mppt(Dc, Strings)
|
||||||
public Decimal ProductionToday { get; init; } // converted to kW in AmptCU class
|
{}
|
||||||
public IReadOnlyList<AmptStringStatus> Strings { get; init; } = null!;
|
|
||||||
}
|
|
|
@ -1,25 +1,27 @@
|
||||||
|
using InnovEnergy.Lib.StatusApi.Connections;
|
||||||
|
using InnovEnergy.Lib.StatusApi.Devices;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Devices.Ampt;
|
namespace InnovEnergy.Lib.Devices.Ampt;
|
||||||
|
|
||||||
public record AmptStatus
|
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<AmptDeviceStatus> 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<AmptDeviceStatus> Devices { get; init; } = null!;
|
|
||||||
}
|
}
|
|
@ -9,6 +9,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="../../Utils/Utils.csproj" />
|
<ProjectReference Include="../../Utils/Utils.csproj" />
|
||||||
<ProjectReference Include="../../Protocols/Modbus/Modbus.csproj" />
|
<ProjectReference Include="../../Protocols/Modbus/Modbus.csproj" />
|
||||||
|
<ProjectReference Include="../../StatusApi/StatusApi.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using InnovEnergy.Lib.Protocols.Modbus.Clients;
|
using InnovEnergy.Lib.Protocols.Modbus.Clients;
|
||||||
using InnovEnergy.Lib.Protocols.Modbus.Connections;
|
using InnovEnergy.Lib.Protocols.Modbus.Connections;
|
||||||
|
using InnovEnergy.Lib.Protocols.Modbus.Conversions;
|
||||||
|
using InnovEnergy.Lib.StatusApi.Connections;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Devices.Battery48TL;
|
namespace InnovEnergy.Lib.Devices.Battery48TL;
|
||||||
|
|
||||||
|
@ -33,6 +35,7 @@ public class Battery48TlDevice
|
||||||
{
|
{
|
||||||
if (Modbus is null) // TODO : remove fake
|
if (Modbus is null) // TODO : remove fake
|
||||||
{
|
{
|
||||||
|
Console.WriteLine("Battery is null");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,13 +44,101 @@ public class Battery48TlDevice
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var registers = Modbus.ReadInputRegisters(Constants.BaseAddress, Constants.NoOfRegisters);
|
var registers = Modbus.ReadInputRegisters(Constants.BaseAddress, Constants.NoOfRegisters);
|
||||||
return new Battery48TLStatus(registers);
|
return TryReadStatus(registers);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Console.WriteLine(e.Message);
|
Console.WriteLine(e.Message + " Battery ");
|
||||||
Modbus.CloseConnection();
|
Modbus.CloseConnection();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Battery48TLStatus? TryReadStatus(ModbusRegisters data)
|
||||||
|
{
|
||||||
|
var soc = data.ParseDecimal(register: 1054, scaleFactor: 0.1m);
|
||||||
|
var eocReached = data.ParseEocReached();
|
||||||
|
|
||||||
|
var warnings = new List<String>();
|
||||||
|
|
||||||
|
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<String>();
|
||||||
|
|
||||||
|
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()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,118 +1,39 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using InnovEnergy.Lib.Protocols.Modbus.Conversions;
|
using InnovEnergy.Lib.Protocols.Modbus.Conversions;
|
||||||
|
using InnovEnergy.Lib.StatusApi.Connections;
|
||||||
|
using InnovEnergy.Lib.StatusApi.Devices;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Devices.Battery48TL;
|
namespace InnovEnergy.Lib.Devices.Battery48TL;
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
[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<String> Warnings,
|
||||||
|
IReadOnlyList<String> 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<String> Warnings { get; }
|
|
||||||
public IReadOnlyList<String> 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<String>();
|
|
||||||
|
|
||||||
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<String>();
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,22 @@ public static class BatteryDataParser
|
||||||
return pLimit;
|
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)
|
internal static Decimal CalcMaxChargePower(this ModbusRegisters data)
|
||||||
{
|
{
|
||||||
var v = ReadVoltage(data);
|
var v = ReadVoltage(data);
|
||||||
|
@ -133,13 +149,15 @@ public static class BatteryDataParser
|
||||||
{
|
{
|
||||||
var v = ReadVoltage(data);
|
var v = ReadVoltage(data);
|
||||||
var i = ReadCurrent(data);
|
var i = ReadCurrent(data);
|
||||||
|
var t = data.ParseDecimal(register: 1004, scaleFactor: 0.1m, offset: -400);
|
||||||
|
|
||||||
var pLimits = new[]
|
var pLimits = new[]
|
||||||
{
|
{
|
||||||
CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMin, Constants.RIntMin),
|
CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMin, Constants.RIntMin),
|
||||||
CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMin, Constants.RIntMax),
|
CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMin, Constants.RIntMax),
|
||||||
CalcPowerLimitImposedByCurrentLimit(v, i, -Constants.IMax, Constants.RIntMin),
|
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();
|
var pLimit = pLimits.Max();
|
||||||
|
|
|
@ -29,7 +29,4 @@ public static class Constants
|
||||||
public const Decimal RIntMin = RStringMin / NumberOfStrings;
|
public const Decimal RIntMin = RStringMin / NumberOfStrings;
|
||||||
public const Decimal RIntMax = RStringMax / NumberOfStrings;
|
public const Decimal RIntMax = RStringMax / NumberOfStrings;
|
||||||
public const Decimal IMax = NumberOfStrings * IMaxPerString;
|
public const Decimal IMax = NumberOfStrings * IMaxPerString;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -9,6 +9,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="../../Utils/Utils.csproj" />
|
<ProjectReference Include="../../Utils/Utils.csproj" />
|
||||||
<ProjectReference Include="../../Protocols/Modbus/Modbus.csproj" />
|
<ProjectReference Include="../../Protocols/Modbus/Modbus.csproj" />
|
||||||
|
<ProjectReference Include="../../StatusApi/StatusApi.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="../../../Protocols/Modbus/Modbus.csproj" />
|
<ProjectReference Include="../../../Protocols/Modbus/Modbus.csproj" />
|
||||||
|
<ProjectReference Include="../../../StatusApi/StatusApi.csproj" />
|
||||||
<ProjectReference Include="../TruConvert/TruConvert.csproj" />
|
<ProjectReference Include="../TruConvert/TruConvert.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ public record TruConvertAcControl
|
||||||
public AcErrorPolicy ErrorHandlingPolicy { get; init;} = 0;
|
public AcErrorPolicy ErrorHandlingPolicy { get; init;} = 0;
|
||||||
public AcDcGridType GridType { get; init;} = 0;
|
public AcDcGridType GridType { get; init;} = 0;
|
||||||
public UInt16 SubSlaveAddress { 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 UInt16 SubSlaveErrorPolicy { get; init;} = 0; // must be an enum
|
||||||
public Decimal SignedPowerNominalValue { get; init;} = 0; // resolution 0.001 and Unit kva,
|
public Decimal SignedPowerNominalValue { get; init;} = 0; // resolution 0.001 and Unit kva,
|
||||||
public Decimal SignedPowerSetValueL1 { 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 MaxPeakCurrentVoltageControlL2 { get; init;} = 0; // resolution 0.01
|
||||||
public Decimal MaxPeakCurrentVoltageControlL3 { 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 GridFormingMode { get; init;} = 1; // 0 = not grid-forming (grid-tied) ,1 = grid-forming
|
||||||
public UInt16 DcLinkRefVoltage { get; init;} = 850;
|
public UInt16 DcLinkRefVoltage { get; init;} = 800;
|
||||||
public UInt16 DcLinkMinVoltage { get; init;} = 830;
|
public UInt16 DcLinkMinVoltage { get; init;} = 780;
|
||||||
public UInt16 DcLinkMaxVoltage { get; init;} = 870;
|
public UInt16 DcLinkMaxVoltage { get; init;} = 820;
|
||||||
public UInt16 DcVoltageRefUs { get; init;} = 900;
|
public UInt16 DcVoltageRefUs { get; init;} = 900;
|
||||||
public UInt16 DcMinVoltageUs { get; init;} = 880;
|
public UInt16 DcMinVoltageUs { get; init;} = 880;
|
||||||
public UInt16 DcMaxVoltageUs { get; init;} = 920;
|
public UInt16 DcMaxVoltageUs { get; init;} = 920;
|
||||||
|
|
|
@ -2,7 +2,10 @@ using System.Diagnostics.CodeAnalysis;
|
||||||
using InnovEnergy.Lib.Devices.Trumpf.TruConvert;
|
using InnovEnergy.Lib.Devices.Trumpf.TruConvert;
|
||||||
using InnovEnergy.Lib.Protocols.Modbus.Clients;
|
using InnovEnergy.Lib.Protocols.Modbus.Clients;
|
||||||
using InnovEnergy.Lib.Protocols.Modbus.Connections;
|
using InnovEnergy.Lib.Protocols.Modbus.Connections;
|
||||||
|
using InnovEnergy.Lib.StatusApi.Connections;
|
||||||
|
using InnovEnergy.Lib.StatusApi.Phases;
|
||||||
using InnovEnergy.Lib.Utils;
|
using InnovEnergy.Lib.Utils;
|
||||||
|
using static DecimalMath.DecimalEx;
|
||||||
using static InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.AcControlRegisters;
|
using static InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.AcControlRegisters;
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,6 +42,8 @@ public class TruConvertAcDevice
|
||||||
WriteRegs(CommunicationTimeout, c.CommunicationTimeout.TotalSeconds.ConvertTo<UInt16>());
|
WriteRegs(CommunicationTimeout, c.CommunicationTimeout.TotalSeconds.ConvertTo<UInt16>());
|
||||||
|
|
||||||
WriteRegs(ConnectedSystemConfig, c.ConnectedSystemConfig);
|
WriteRegs(ConnectedSystemConfig, c.ConnectedSystemConfig);
|
||||||
|
|
||||||
|
|
||||||
WriteCoils(PowerStageConfig, c.PowerStageEnable,
|
WriteCoils(PowerStageConfig, c.PowerStageEnable,
|
||||||
c.SetValueConfig.ConvertTo<Boolean>(),
|
c.SetValueConfig.ConvertTo<Boolean>(),
|
||||||
c.ResetsAlarmAndWarning);
|
c.ResetsAlarmAndWarning);
|
||||||
|
@ -92,6 +97,8 @@ public class TruConvertAcDevice
|
||||||
private void WriteRegs (UInt16 a, params UInt16[] regs) => ModbusTcpClient.WriteRegisters(a, regs);
|
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 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()
|
public TruConvertAcStatus? ReadStatus()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -112,115 +119,171 @@ public class TruConvertAcDevice
|
||||||
{
|
{
|
||||||
// Console.WriteLine("Reading Ac Device");
|
// Console.WriteLine("Reading Ac Device");
|
||||||
|
|
||||||
var acActualMain = ModbusTcpClient.ReadInputRegisters(5001, 3);
|
var acSerialNumber = ModbusTcpClient.ReadInputRegisters(2009, 2);
|
||||||
var acActualAcDc = ModbusTcpClient.ReadInputRegisters(5021, 9);
|
var acActualMain = ModbusTcpClient.ReadInputRegisters(5001, 3);
|
||||||
var acActualAcDc2 = ModbusTcpClient.ReadInputRegisters(5031, 1);
|
var acActualAcDc = ModbusTcpClient.ReadInputRegisters(5021, 9);
|
||||||
var acActualAcDc3 = ModbusTcpClient.ReadInputRegisters(5131, 6);
|
var acActualAcDc2 = ModbusTcpClient.ReadInputRegisters(5031, 1);
|
||||||
var acActualMeasurement = ModbusTcpClient.ReadInputRegisters(5141, 3);
|
var acActualAcDc3 = ModbusTcpClient.ReadInputRegisters(5131, 6);
|
||||||
var acActualMeasurement1 = ModbusTcpClient.ReadInputRegisters(5151, 3);
|
var acActualMeasurement = ModbusTcpClient.ReadInputRegisters(5141, 3);
|
||||||
var acActualMeasurement2 = ModbusTcpClient.ReadInputRegisters(5161, 3);
|
var acActualMeasurement1 = ModbusTcpClient.ReadInputRegisters(5151, 3);
|
||||||
var acActualMeasurement3 = ModbusTcpClient.ReadInputRegisters(5171, 3);
|
var acActualMeasurement2 = ModbusTcpClient.ReadInputRegisters(5161, 3);
|
||||||
var acActualMeasurement4 = ModbusTcpClient.ReadInputRegisters(5187, 2);
|
var acActualMeasurement3 = ModbusTcpClient.ReadInputRegisters(5171, 3);
|
||||||
var acActualMeasurement5 = ModbusTcpClient.ReadInputRegisters(5189, 2);
|
var acActualMeasurement4 = ModbusTcpClient.ReadInputRegisters(5187, 2);
|
||||||
var acActualMeasurement6 = ModbusTcpClient.ReadInputRegisters(5191, 2);
|
var acActualMeasurement5 = ModbusTcpClient.ReadInputRegisters(5189, 2);
|
||||||
var acActualMeasurement7 = ModbusTcpClient.ReadInputRegisters(5201, 1);
|
var acActualMeasurement6 = ModbusTcpClient.ReadInputRegisters(5191, 2);
|
||||||
var acActualMeasurement8 = ModbusTcpClient.ReadInputRegisters(5211, 4);
|
var acActualMeasurement7 = ModbusTcpClient.ReadInputRegisters(5201, 1);
|
||||||
var acActualMeasurement9 = ModbusTcpClient.ReadInputRegisters(5221, 2);
|
var acActualMeasurement8 = ModbusTcpClient.ReadInputRegisters(5211, 4);
|
||||||
var acActualTemp = ModbusTcpClient.ReadInputRegisters(5501, 1);
|
var acActualMeasurement9 = ModbusTcpClient.ReadInputRegisters(5221, 2);
|
||||||
var acWarningValues = ModbusTcpClient.ReadInputRegisters(2402, 22);
|
var acActualTemp = ModbusTcpClient.ReadInputRegisters(5501, 1);
|
||||||
var acAlarmValues = ModbusTcpClient.ReadInputRegisters(2809, 22);
|
var acWarningValues = ModbusTcpClient.ReadInputRegisters(2402, 22);
|
||||||
var acSetValues = ModbusTcpClient.ReadInputRegisters(4196, 1);
|
var acAlarmValues = ModbusTcpClient.ReadInputRegisters(2809, 22);
|
||||||
|
var acSetValues = ModbusTcpClient.ReadInputRegisters(4196, 1);
|
||||||
|
|
||||||
var warnings = Enumerable
|
var warnings = Enumerable
|
||||||
.Range(2404, 20)
|
.Range(2404, 20)
|
||||||
.Select(n => acWarningValues.GetUInt16((UInt16)n).ConvertTo<WarningMessage>())
|
.Select(n => acWarningValues.GetUInt16((UInt16)n).ConvertTo<WarningMessage>())
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
var alarms = Enumerable
|
var alarms = Enumerable
|
||||||
.Range(2811, 20)
|
.Range(2811, 20)
|
||||||
.Select(n => acAlarmValues.GetUInt16((UInt16)n).ConvertTo<AlarmMessage>())
|
.Select(n => acAlarmValues.GetUInt16((UInt16)n).ConvertTo<AlarmMessage>())
|
||||||
.Where(m => m != AlarmMessage.NoAlarm)
|
.Where(m => m != AlarmMessage.NoAlarm)
|
||||||
.ToArray();
|
.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
|
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
|
// acActualMainValues
|
||||||
MainState = acActualMain.GetInt16(5001).ConvertTo<MainState>(),
|
MainState : acActualMain.GetInt16(5001).ConvertTo<MainState>(),
|
||||||
NumberOfConnectedSlaves = acActualMain.GetUInt16(5002),
|
NumberOfConnectedSlaves : acActualMain.GetUInt16(5002),
|
||||||
NumberOfConnectedSubSlaves = acActualMain.GetUInt16(5003),
|
NumberOfConnectedSubSlaves : acActualMain.GetUInt16(5003),
|
||||||
|
|
||||||
//acActualAcDc
|
//acActualAcDc
|
||||||
AcDcNominalGridFrequency = acActualAcDc.GetUInt16(5021) * 0.1m,
|
AcDcNominalGridFrequency : acActualAcDc.GetUInt16(5021) * 0.1m,
|
||||||
AcDcNominalGridVoltage = acActualAcDc.GetUInt16(5022),
|
AcDcNominalGridVoltage : acActualAcDc.GetUInt16(5022),
|
||||||
AcDcActNominalPower = acActualAcDc.GetUInt16(5023),
|
AcDcActNominalPower : acActualAcDc.GetUInt16(5023),
|
||||||
AcDcActiveGridType = acActualAcDc.GetUInt16(5024).ConvertTo<AcDcGridType>(),
|
AcDcActiveGridType : acActualAcDc.GetUInt16(5024).ConvertTo<AcDcGridType>(),
|
||||||
AcDcPowerLimitingStatusAct = acActualAcDc.GetUInt16(5025),
|
AcDcPowerLimitingStatusAct : acActualAcDc.GetUInt16(5025),
|
||||||
AcDcDcVoltageReference = acActualAcDc.GetUInt16(5026), // DC link reference
|
AcDcDcVoltageReference : acActualAcDc.GetUInt16(5026), // DC link reference
|
||||||
AcDcDcLinkVoltageMinAct = acActualAcDc.GetUInt16(5027), // DC link min voltage
|
AcDcDcLinkVoltageMinAct : acActualAcDc.GetUInt16(5027), // DC link min voltage
|
||||||
AcDcDcLinkVoltageMaxAct = acActualAcDc.GetUInt16(5028), // DC link max voltage
|
AcDcDcLinkVoltageMaxAct : acActualAcDc.GetUInt16(5028), // DC link max voltage
|
||||||
AcDcDcLinkChargedMinVoltage = acActualAcDc.GetUInt16(5029) * 0.01m,
|
AcDcDcLinkChargedMinVoltage : acActualAcDc.GetUInt16(5029) * 0.01m,
|
||||||
|
|
||||||
//ac Actual AcDc 2
|
//ac Actual AcDc 2
|
||||||
AcDcStmActCustomer = acActualAcDc2.GetUInt16(5031), //need to check
|
AcDcStmActCustomer : acActualAcDc2.GetUInt16(5031), //need to check
|
||||||
|
AcDcOverloadIntegratorStatusL1 : acActualAcDc3.GetUInt16(5134) * 0.1m,
|
||||||
ApparentPowerAcL1 = acActualAcDc3.GetUInt16(5131) * 1m, // in VA
|
AcDcOverloadIntegratorStatusL2 : acActualAcDc3.GetUInt16(5135) * 0.1m,
|
||||||
ApparentPowerAcL2 = acActualAcDc3.GetUInt16(5132) * 1m, // in VA
|
AcDcOverloadIntegratorStatusL3 : acActualAcDc3.GetUInt16(5136) * 0.1m,
|
||||||
ApparentPowerAcL3 = acActualAcDc3.GetUInt16(5133) * 1m, // in VA
|
AcSignedPowerValue : acSetValues.GetInt16(4196) * -1.0m, // this is also used for control
|
||||||
|
|
||||||
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,
|
|
||||||
|
|
||||||
//acActualMeasurement10
|
//acActualMeasurement10
|
||||||
ActualDcLinkVoltageUpperHalf = acActualMeasurement8.GetUInt16(5211),
|
ActualDcLinkVoltageUpperHalf : acActualMeasurement8.GetUInt16(5211),
|
||||||
ActualDcLinkVoltageLowerHalf = acActualMeasurement8.GetUInt16(5212),
|
ActualDcLinkVoltageLowerHalf : acActualMeasurement8.GetUInt16(5212),
|
||||||
ActualDcLinkVoltageUpperHalfExt = acActualMeasurement8.GetUInt16(5213),
|
ActualDcLinkVoltageUpperHalfExt : acActualMeasurement8.GetUInt16(5213),
|
||||||
ActualDcLinkVoltageLowerHalfExt = acActualMeasurement8.GetUInt16(5214),
|
ActualDcLinkVoltageLowerHalfExt : acActualMeasurement8.GetUInt16(5214),
|
||||||
|
|
||||||
//acActualMeasurement11
|
|
||||||
VoltageIntNtoPE = acActualMeasurement9.GetInt16(5221) * 0.1m,
|
|
||||||
VoltageExtNtoPE = acActualMeasurement9.GetInt16(5222) * 0.1m,
|
|
||||||
|
|
||||||
|
VoltageIntNtoPe : acActualMeasurement9.GetInt16(5221) * 0.1m,
|
||||||
|
VoltageExtNtoPe : acActualMeasurement9.GetInt16(5222) * 0.1m,
|
||||||
//acActualTemp
|
//acActualTemp
|
||||||
InletAirTemperature = acActualTemp.GetInt16(5501) * 0.1m,
|
InletAirTemperature : acActualTemp.GetInt16(5501) * 0.1m,
|
||||||
|
|
||||||
Warnings = warnings,
|
Warnings : warnings,
|
||||||
Alarms = alarms,
|
Alarms : alarms
|
||||||
|
);
|
||||||
// acSetValues
|
|
||||||
AcSignedPowerValue = acSetValues.GetInt16(4196) * -1.0m, // this is also used for control
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,60 +1,43 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using InnovEnergy.Lib.Devices.Trumpf.TruConvert;
|
using InnovEnergy.Lib.Devices.Trumpf.TruConvert;
|
||||||
|
using InnovEnergy.Lib.StatusApi.Connections;
|
||||||
|
using InnovEnergy.Lib.StatusApi.Devices;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc;
|
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc;
|
||||||
|
|
||||||
using AlarmMessages = IReadOnlyList<AlarmMessage>;
|
using AlarmMessages = IReadOnlyList<AlarmMessage>;
|
||||||
using WarningMessages = IReadOnlyList<WarningMessage>;
|
using WarningMessages = IReadOnlyList<WarningMessage>;
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
|
||||||
public record TruConvertAcStatus
|
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<WarningMessage>();
|
|
||||||
public AlarmMessages Alarms { get; init; } = Array.Empty<AlarmMessage>();
|
|
||||||
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
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -10,6 +10,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="../../../Protocols/Modbus/Modbus.csproj" />
|
<ProjectReference Include="../../../Protocols/Modbus/Modbus.csproj" />
|
||||||
<ProjectReference Include="../TruConvert/TruConvert.csproj" />
|
<ProjectReference Include="../TruConvert/TruConvert.csproj" />
|
||||||
|
<ProjectReference Include="../../../StatusApi/StatusApi.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ public record TruConvertDcControl
|
||||||
public Boolean ResetParamToDefault { get; init;} = false ; // Coil
|
public Boolean ResetParamToDefault { get; init;} = false ; // Coil
|
||||||
public TimeSpan TimeoutForCommunication { get; init;} = DefaultCommunicationTimeOut;
|
public TimeSpan TimeoutForCommunication { get; init;} = DefaultCommunicationTimeOut;
|
||||||
public Boolean RestartFlag { get; init;} = false ; // Coil
|
public Boolean RestartFlag { get; init;} = false ; // Coil
|
||||||
|
|
||||||
public SystemConfig ConnectedSystemConfig { get; init;} = SystemConfig.NoConfig ;
|
public SystemConfig ConnectedSystemConfig { get; init;} = SystemConfig.NoConfig ;
|
||||||
public UInt16 UpdateSwTrigger { get; init;} = 0 ;
|
public UInt16 UpdateSwTrigger { get; init;} = 0 ;
|
||||||
public UInt16 AutomaticSwUpdate { 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 BatteryCurrentSet { get; init;} = 0; // resolution 1.0
|
||||||
public Decimal DynamicCurrentPerMillisecond { get; init;} = 0; // resolution : 0.01
|
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 DcLinkControlMode { get; init;} = 0; // Parameter aktiviert/deaktiviert "DC link voltage droop mode"
|
||||||
public Decimal ReferenceVoltage { get; init;} = 0; // resolution : 0.1
|
public Decimal ReferenceVoltage { get; init;} = 800; // resolution : 0.1
|
||||||
public Decimal UpperVoltageWindow { get; init;} = 0; // resolution : 0.1
|
public Decimal UpperVoltageWindow { get; init;} = 40; // resolution : 0.1
|
||||||
public Decimal LowerVoltageWindow { get; init;} = 0; // resolution : 0.1
|
public Decimal LowerVoltageWindow { get; init;} = 40; // resolution : 0.1
|
||||||
public Decimal VoltageDeadBand { get; init;} = 0; // resolution : 0.1
|
public Decimal VoltageDeadBand { get; init;} = 0; // resolution : 0.1
|
||||||
|
|
||||||
private static readonly TimeSpan DefaultCommunicationTimeOut = TimeSpan.FromMinutes(10);
|
private static readonly TimeSpan DefaultCommunicationTimeOut = TimeSpan.FromMinutes(10);
|
||||||
|
|
|
@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||||
using InnovEnergy.Lib.Devices.Trumpf.TruConvert;
|
using InnovEnergy.Lib.Devices.Trumpf.TruConvert;
|
||||||
using InnovEnergy.Lib.Protocols.Modbus.Clients;
|
using InnovEnergy.Lib.Protocols.Modbus.Clients;
|
||||||
using InnovEnergy.Lib.Protocols.Modbus.Connections;
|
using InnovEnergy.Lib.Protocols.Modbus.Connections;
|
||||||
|
using InnovEnergy.Lib.StatusApi.Connections;
|
||||||
using InnovEnergy.Lib.Utils;
|
using InnovEnergy.Lib.Utils;
|
||||||
using static InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.DcControlRegisters;
|
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
|
// TODO starting from 4000, evaluate what/if needs updating below 4000
|
||||||
|
|
||||||
|
WriteRegs(TimeoutCommunication, c.TimeoutForCommunication.TotalSeconds.ConvertTo<UInt16>());
|
||||||
|
|
||||||
WriteCoils(PowerStageOperation, c.PowerStageEnable);
|
WriteCoils(PowerStageOperation, c.PowerStageEnable);
|
||||||
WriteCoils(ResetsAlarmAndWarning, c.ResetsAlarmAndWarning);
|
WriteCoils(ResetsAlarmAndWarning, c.ResetsAlarmAndWarning);
|
||||||
|
@ -103,18 +105,14 @@ public class TruConvertDcDevice
|
||||||
private TruConvertDcStatus TryReadStatus()
|
private TruConvertDcStatus TryReadStatus()
|
||||||
{
|
{
|
||||||
// Console.WriteLine("Reading DC Device");
|
// Console.WriteLine("Reading DC Device");
|
||||||
|
|
||||||
var dcPrValMain = ModbusTcpClient.ReadInputRegisters(5001, 3);
|
var dcPrValMain = ModbusTcpClient.ReadInputRegisters(5001, 3);
|
||||||
var dcBatteryValue = ModbusTcpClient.ReadInputRegisters(5101, 1);
|
var dcBatteryValue = ModbusTcpClient.ReadInputRegisters(5101, 1);
|
||||||
var dcBatteryValue2 = ModbusTcpClient.ReadInputRegisters(5111, 1);
|
var dcBatteryValue2 = ModbusTcpClient.ReadInputRegisters(5111, 1);
|
||||||
var dcBatteryValue3 = ModbusTcpClient.ReadInputRegisters(5114, 2);
|
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 dcPrValDcDc = ModbusTcpClient.ReadInputRegisters(5124, 1);
|
||||||
var dcPrValDcDc2 = ModbusTcpClient.ReadInputRegisters(5127, 2);
|
var dcPrValDcDc2 = ModbusTcpClient.ReadInputRegisters(5127, 2);
|
||||||
|
|
||||||
var dcTempValue = ModbusTcpClient.ReadInputRegisters(5511, 1);
|
var dcTempValue = ModbusTcpClient.ReadInputRegisters(5511, 1);
|
||||||
|
|
||||||
var dcWarningValues = ModbusTcpClient.ReadInputRegisters(2404, 20);
|
var dcWarningValues = ModbusTcpClient.ReadInputRegisters(2404, 20);
|
||||||
var dcAlarmValues = ModbusTcpClient.ReadInputRegisters(2811, 20);
|
var dcAlarmValues = ModbusTcpClient.ReadInputRegisters(2811, 20);
|
||||||
var dcSetValues = ModbusTcpClient.ReadInputRegisters(4001, 1);
|
var dcSetValues = ModbusTcpClient.ReadInputRegisters(4001, 1);
|
||||||
|
@ -133,37 +131,34 @@ public class TruConvertDcDevice
|
||||||
|
|
||||||
var dcCurrentLimitState = GetFlags(dcPrValDcDc.GetUInt16(5124)).ToArray();
|
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
|
return new TruConvertDcStatus
|
||||||
{
|
(
|
||||||
// dcPrValMain
|
|
||||||
MainState = (MainState) dcPrValMain.GetInt16(5001),
|
|
||||||
NumberOfConnectedSlaves = dcPrValMain.GetUInt16(5002),
|
|
||||||
NumberOfConnectedSubSlaves = dcPrValMain.GetUInt16(5003),
|
|
||||||
|
|
||||||
// dcBatteryValue
|
Dc: new DcConnection
|
||||||
BatteryVoltage = dcBatteryValue.GetUInt16(5101) * 0.1m,
|
(
|
||||||
BatteryCurrent = dcBatteryValue2.GetInt16(5111),
|
dcLinkVoltage,
|
||||||
|
dcCurrent
|
||||||
|
),
|
||||||
|
|
||||||
TotalDcPower = dcBatteryValue3.GetInt32(5114) * 1m, // Resolution is 0.001 (kW) in Tru convert DC doc, but we want it in W
|
MainState : (MainState)dcPrValMain.GetInt16(5001),
|
||||||
|
NumberOfConnectedSlaves : dcPrValMain.GetUInt16(5002),
|
||||||
DcPower = dcBatteryValue4.GetInt16(5121) * 1m, // Resolution is 0.001 (kW) in Tru convert DC doc, but we want it in W
|
NumberOfConnectedSubSlaves : dcPrValMain.GetUInt16(5003),
|
||||||
|
BatteryVoltage : dcBatteryValue.GetUInt16(5101) * 0.1m,
|
||||||
// dcPrValDcDc
|
BatteryCurrent : dcBatteryValue2.GetInt16(5111),
|
||||||
StatusOfCurrentLimiting = dcCurrentLimitState,
|
TotalDcPower : dcBatteryValue3.GetInt32(5114) * 1m, // Resolution is 0.001 (kW) in Tru convert DC doc, but we want it in W
|
||||||
|
StatusOfCurrentLimiting : dcCurrentLimitState,
|
||||||
// dcPrValDcDc2
|
OverloadCapacity : dcPrValDcDc2.GetUInt16(5127) * 0.1m,
|
||||||
OverloadCapacity = dcPrValDcDc2.GetUInt16(5127) * 0.1m,
|
DcDcInletTemperature : dcTempValue.GetInt16(5511),
|
||||||
DcLinkVoltage = dcPrValDcDc2.GetUInt16(5128),
|
Warnings : warnings,
|
||||||
|
Alarms : alarms,
|
||||||
//dcTempValue
|
PowerOperation : dcSetValues.GetBoolean(4001)
|
||||||
DcDcInletTemperature = dcTempValue.GetInt16(5511),
|
);
|
||||||
|
|
||||||
Warnings = warnings,
|
|
||||||
Alarms = alarms,
|
|
||||||
|
|
||||||
// dcSetValues
|
|
||||||
PowerOperation = dcSetValues.GetBoolean(4001)
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
using InnovEnergy.Lib.Devices.Trumpf.TruConvert;
|
using InnovEnergy.Lib.Devices.Trumpf.TruConvert;
|
||||||
|
using InnovEnergy.Lib.StatusApi.Connections;
|
||||||
|
using InnovEnergy.Lib.StatusApi.Devices;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc;
|
namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertDc;
|
||||||
|
|
||||||
|
@ -7,21 +9,19 @@ using WarningMessages = IReadOnlyList<WarningMessage>;
|
||||||
using DcCurrentLimitStates = IReadOnlyList<DcCurrentLimitState>;
|
using DcCurrentLimitStates = IReadOnlyList<DcCurrentLimitState>;
|
||||||
|
|
||||||
public record TruConvertDcStatus
|
public record TruConvertDcStatus
|
||||||
{
|
(
|
||||||
public MainState MainState { get; init; }
|
DcConnection Dc,
|
||||||
public UInt16 NumberOfConnectedSlaves { get; init; }
|
MainState MainState,
|
||||||
public UInt16 NumberOfConnectedSubSlaves { get; init; }
|
UInt16 NumberOfConnectedSlaves,
|
||||||
public Decimal BatteryVoltage { get; init; }
|
UInt16 NumberOfConnectedSubSlaves,
|
||||||
public Decimal BatteryCurrent { get; init; }
|
Decimal BatteryVoltage,
|
||||||
public Decimal TotalDcPower { get; init; }
|
Decimal BatteryCurrent,
|
||||||
public Decimal DcPower { get; init; }
|
Decimal TotalDcPower,
|
||||||
public DcCurrentLimitStates StatusOfCurrentLimiting { get; init; } = Array.Empty<DcCurrentLimitState>();
|
DcCurrentLimitStates StatusOfCurrentLimiting,
|
||||||
public Decimal OverloadCapacity { get; init; }
|
Decimal OverloadCapacity,
|
||||||
public Decimal DcLinkVoltage { get; init; }
|
Decimal DcDcInletTemperature,
|
||||||
public Decimal DcDcInletTemperature { get; init; }
|
AlarmMessages Alarms,
|
||||||
public AlarmMessages Alarms { get; init; } = Array.Empty<AlarmMessage>();
|
WarningMessages Warnings,
|
||||||
public WarningMessages Warnings { get; init; } = Array.Empty<WarningMessage>();
|
Boolean PowerOperation
|
||||||
|
):DcDevice(Dc)
|
||||||
public Boolean PowerOperation { get; init; }
|
{}
|
||||||
|
|
||||||
}
|
|
|
@ -1,9 +1,8 @@
|
||||||
using InnovEnergy.Lib.StatusApi.Phases;
|
using InnovEnergy.Lib.StatusApi.Phases;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.StatusApi.Connections;
|
namespace InnovEnergy.Lib.StatusApi.Connections;
|
||||||
|
|
||||||
|
|
||||||
public record DcConnection(Decimal Voltage, Decimal Current) : Phase(Voltage, Current)
|
public record DcConnection(Decimal Voltage, Decimal Current) : Phase(Voltage, Current)
|
||||||
{
|
{
|
||||||
public Decimal Power => Current * Voltage;
|
public Decimal Power => (Current * Voltage).Round3();
|
||||||
}
|
}
|
|
@ -3,10 +3,10 @@ using InnovEnergy.Lib.StatusApi.Phases;
|
||||||
namespace InnovEnergy.Lib.StatusApi.Connections;
|
namespace InnovEnergy.Lib.StatusApi.Connections;
|
||||||
|
|
||||||
public record SinglePhaseAcConnection
|
public record SinglePhaseAcConnection
|
||||||
(
|
(
|
||||||
Decimal Voltage,
|
Decimal Voltage,
|
||||||
Decimal Current,
|
Decimal Current,
|
||||||
Decimal Phi,
|
Decimal Phi,
|
||||||
Decimal Frequency
|
Decimal Frequency
|
||||||
)
|
);
|
||||||
: AcPhase(Voltage, Current, Phi);
|
//: AcPhase(Voltage, Current, Phi);
|
|
@ -21,12 +21,12 @@ public record AcPhase
|
||||||
public static AcPhase FromActiveReactive
|
public static AcPhase FromActiveReactive
|
||||||
(
|
(
|
||||||
Decimal activePower,
|
Decimal activePower,
|
||||||
Decimal reactivePower,
|
Decimal apparentPower,
|
||||||
Decimal voltage,
|
Decimal voltage,
|
||||||
Decimal current
|
Decimal current
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
var apparentPower = Sqrt(activePower * activePower + reactivePower * reactivePower);
|
var reactivePower = Sqrt(Math.Abs(apparentPower * apparentPower - activePower * activePower ));
|
||||||
var phi = ATan2(reactivePower, activePower);
|
var phi = ATan2(reactivePower, activePower);
|
||||||
|
|
||||||
return new AcPhase
|
return new AcPhase
|
||||||
|
@ -39,11 +39,10 @@ public record AcPhase
|
||||||
ReactivePower: reactivePower,
|
ReactivePower: reactivePower,
|
||||||
PowerFactor: Cos(phi)
|
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);
|
var powerFactor = Cos(phi);
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CliWrap" Version="3.3.1" />
|
<PackageReference Include="CliWrap" Version="3.6.0" />
|
||||||
<PackageReference Include="DecimalMath.DecimalEx" Version="1.0.2" />
|
<PackageReference Include="DecimalMath.DecimalEx" Version="1.0.2" />
|
||||||
<PackageReference Include="System.Reactive.Linq" Version="5.0.0" />
|
<PackageReference Include="System.Reactive.Linq" Version="5.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
Loading…
Reference in New Issue