Compare commits

..

5 Commits

Author SHA1 Message Date
atef abd2d24e6c Update Adam6360D and Relay class 2024-11-26 11:36:48 +01:00
atef 1b26427e52 Update Salimax to SodiStore 2024-11-26 11:29:40 +01:00
atef 32191f3821 update schneider Meter 2024-11-26 11:29:17 +01:00
atef 8bb1287864 spellcheck 2024-11-26 11:24:11 +01:00
atef a5c6d7ecb2 Update Emu meter driver for Victron 2024-11-26 11:20:34 +01:00
9 changed files with 111 additions and 56 deletions

View File

@ -28,12 +28,12 @@ public static class Config
new(s => s.Ac.L1.Voltage, "/Ac/L1/Voltage", "0.0 A"), new(s => s.Ac.L1.Voltage, "/Ac/L1/Voltage", "0.0 A"),
new(s => s.Ac.L2.Voltage, "/Ac/L2/Voltage", "0.0 A"), new(s => s.Ac.L2.Voltage, "/Ac/L2/Voltage", "0.0 A"),
new(s => s.Ac.L3.Voltage, "/Ac/L3/Voltage", "0.0 A"), new(s => s.Ac.L3.Voltage, "/Ac/L3/Voltage", "0.0 A"),
new(s => (s.Ac.L1.Voltage + s.Ac.L2.Voltage + s.Ac.L3.Voltage) / 3.0m, "/Ac/Voltage", "0.0 A"), new(s => (s.Ac.L1.Voltage + s.Ac.L2.Voltage + s.Ac.L3.Voltage) / 3, "/Ac/Voltage", "0.0 A"),
new(s => s.Ac.L1.ActivePower, "/Ac/L1/Power", "0 W"), new(s => s.Ac.L1.Power.Active, "/Ac/L1/Power", "0 W"),
new(s => s.Ac.L2.ActivePower, "/Ac/L2/Power", "0 W"), new(s => s.Ac.L2.Power.Active, "/Ac/L2/Power", "0 W"),
new(s => s.Ac.L3.ActivePower, "/Ac/L3/Power", "0 W"), new(s => s.Ac.L3.Power.Active, "/Ac/L3/Power", "0 W"),
new(s => s.Ac.ActivePower, "/Ac/Power", "0 W"), new(s => s.Ac.Power.Active, "/Ac/Power", "0 W"),
// new(s => s.EnergyImportL123, "Ac/Energy/Forward", "0.00 kWh"), // new(s => s.EnergyImportL123, "Ac/Energy/Forward", "0.00 kWh"),
// new(s => s.EnergyExportL123, "Ac/Energy/Reverse", "0.00 kWh"), // new(s => s.EnergyExportL123, "Ac/Energy/Reverse", "0.00 kWh"),

View File

@ -25,7 +25,7 @@ public static class EmuMeterDriver
var meterStatus = Observable var meterStatus = Observable
.Interval(Config.UpdatePeriod) .Interval(Config.UpdatePeriod)
.Select(_ => emuMeter.ReadStatus()) .Select(_ => emuMeter.Read())
.Publish(); .Publish();
var poller = meterStatus.Connect(); var poller = meterStatus.Connect();

View File

@ -6,9 +6,9 @@ namespace InnovEnergy.App.EmuMeterDriver;
// TODO: Does not compile // TODO: Does not compile
public record Signal(Func<EmuMeterStatus, Object> Source, ObjectPath Path, String Format = "") public record Signal(Func<EmuMeterRegisters, Object> Source, ObjectPath Path, String Format = "")
{ {
public VeProperty ToVeProperty(EmuMeterStatus status) public VeProperty ToVeProperty(EmuMeterRegisters status)
{ {
var value = Source(status); var value = Source(status);
return new VeProperty(Path, value, String.Format($"{{0:{Format}}}", value)); return new VeProperty(Path, value, String.Format($"{{0:{Format}}}", value));

View File

@ -0,0 +1,61 @@
#!/bin/bash
csproj="SchneiderMeterDriver.csproj"
exe="SchneiderMeterDriver"
remote="10.2.4.114"
platform="linux-arm"
netVersion="net6.0"
config="Release"
host="root@$remote"
dir="/opt/innovenergy/$exe"
log_dir="/var/log/SchneiderMeterDriver"
set -e
# Publish the project locally
dotnet publish "$csproj" -c $config -r $platform -p:SuppressTrimmAnalysisWarnings=true -p:PublishSingleFile=true -p:PublishTrimmed=true -p:DebugType=None -p:DebugSymbols=false --self-contained true
# Sync the published files to the remote server
rsync -av "bin/$config/$netVersion/$platform/publish/" "$host:$dir"
# Execute commands on the remote server
ssh "$host" << 'EOF'
set -e
# Remount the root filesystem with read and write permissions
mount -o remount,rw /
# Create service and log directories
mkdir -p /opt/innovenergy/SchneiderMeterDriver/service
mkdir -p /opt/innovenergy/SchneiderMeterDriver/service/log
mkdir -p /var/log/SchneiderMeterDriver
# Create the service run script
cat << 'EOL' > /opt/innovenergy/SchneiderMeterDriver/service/run
#!/bin/sh
exec 2>&1
exec softlimit -d 200000000 -s 2000000 -a 200000000 /opt/innovenergy/SchneiderMeterDriver/SchniederDriver
EOL
chmod +x /opt/innovenergy/SchneiderMeterDriver/service/run
# Create the log run script
cat << 'EOL' > /opt/innovenergy/SchneiderMeterDriver/service/log/run
#!/bin/sh
exec 2>&1
exec multilog t s25000 n4 /var/log/SchneiderMeterDriver
EOL
chmod +x /opt/innovenergy/SchneiderMeterDriver/service/log/run
# Create the symbolic link for the service
ln -sf /opt/innovenergy/SchneiderMeterDriver/service /service/SchneiderMeterDriver
# Wait a bit for the symlink to be recognized
sleep 2
# Start the service
start SchneiderMeterDriver
EOF
echo "Deployment and service setup completed successfully."

View File

@ -118,7 +118,7 @@ internal static class Program
private static async Task Run() private static async Task Run()
{ {
"Starting SaliMax".WriteLine(); "Starting SodiStore Max".WriteLine();
Watchdog.NotifyReady(); Watchdog.NotifyReady();
@ -317,7 +317,6 @@ internal static class Program
var bWarningList = new List<String>(); var bWarningList = new List<String>();
if (record.Battery != null) if (record.Battery != null)
{ {
var i = 0; var i = 0;
@ -554,7 +553,7 @@ internal static class Program
const Double voltageRange = 100; // 100 Voltage configured rang for PV slope, if the configured slope change this must change also const Double voltageRange = 100; // 100 Voltage configured rang for PV slope, if the configured slope change this must change also
var configFile = r.Config; var configFile = r.Config;
var inverters = r.AcDc.Devices; var inverters = r.AcDc.Devices;
var systemExportLimit = -exportLimit * 1000 ; // Conversion from Kw in W var systemExportLimit = - exportLimit * 1000 ; // Conversion from Kw in W // the config file value is positive and limit should be negative from 0 to ...
var stepSize = ClampStepSize((UInt16)Math.Floor(voltageRange/ pvInstalledPower)); // in Voltage per 1 Kw var stepSize = ClampStepSize((UInt16)Math.Floor(voltageRange/ pvInstalledPower)); // in Voltage per 1 Kw
var deadBand = constantDeadBand/stepSize; var deadBand = constantDeadBand/stepSize;
@ -565,7 +564,17 @@ internal static class Program
.Distinct() .Distinct()
.ToList(); .ToList();
var upperVoltage = result.Count == 1 ? result[0] : 0; Double upperVoltage;
if (result.Count == 1)
{
upperVoltage = result[0];
}
else
{
Console.WriteLine(" Different ActiveUpperVoltage between inverters ");
return;
}
/************* For debugging purposes ********************/ /************* For debugging purposes ********************/

View File

@ -11,6 +11,11 @@ public interface IRelaysRecord
Boolean FiWarning { get; } Boolean FiWarning { get; }
Boolean FiError { get; } Boolean FiError { get; }
Boolean K2ConnectIslandBusToGridBus { get; set; } Boolean K2ConnectIslandBusToGridBus { get; set; }
Boolean Wago1Status { get; } //need to assign names to the Wago 1,2 ...
Boolean Wago2Status { get; } //need to assign names to the Wago 1,2 ...
Boolean Wago3Status { get; } //need to assign names to the Wago 1,2 ...
Boolean Wago4Status { get; } //need to assign names to the Wago 1,2 ...
} }
public class RelaysRecord : IRelaysRecord public class RelaysRecord : IRelaysRecord
@ -22,6 +27,11 @@ public class RelaysRecord : IRelaysRecord
public Boolean K1GridBusIsConnectedToGrid => _Regs.DigitalInput6; public Boolean K1GridBusIsConnectedToGrid => _Regs.DigitalInput6;
public Boolean K2IslandBusIsConnectedToGridBus => !_Regs.DigitalInput4; public Boolean K2IslandBusIsConnectedToGridBus => !_Regs.DigitalInput4;
public Boolean Wago1Status => _Regs.DigitalInput8;
public Boolean Wago2Status => _Regs.DigitalInput9;
public Boolean Wago3Status => _Regs.DigitalInput10;
public Boolean Wago4Status => _Regs.DigitalInput11;
public IEnumerable<Boolean> K3InverterIsConnectedToIslandBus public IEnumerable<Boolean> K3InverterIsConnectedToIslandBus
{ {
get get
@ -33,10 +43,10 @@ public class RelaysRecord : IRelaysRecord
} }
} }
public Boolean K3Inverter1IsConnectedToIslandBus => !_Regs.DigitalInput0; private Boolean K3Inverter1IsConnectedToIslandBus => !_Regs.DigitalInput0; // change it to private should be ok
public Boolean K3Inverter2IsConnectedToIslandBus => !_Regs.DigitalInput1; private Boolean K3Inverter2IsConnectedToIslandBus => !_Regs.DigitalInput1;
public Boolean K3Inverter3IsConnectedToIslandBus => !_Regs.DigitalInput2; private Boolean K3Inverter3IsConnectedToIslandBus => !_Regs.DigitalInput2;
public Boolean K3Inverter4IsConnectedToIslandBus => !_Regs.DigitalInput3; private Boolean K3Inverter4IsConnectedToIslandBus => !_Regs.DigitalInput3;
public Boolean FiWarning => !_Regs.DigitalInput5; public Boolean FiWarning => !_Regs.DigitalInput5;
public Boolean FiError => !_Regs.DigitalInput7; public Boolean FiError => !_Regs.DigitalInput7;
@ -58,6 +68,11 @@ public class RelaysRecordAmax : IRelaysRecord
public Boolean K1GridBusIsConnectedToGrid => _Regs.DigitalInput22; public Boolean K1GridBusIsConnectedToGrid => _Regs.DigitalInput22;
public Boolean K2IslandBusIsConnectedToGridBus => !_Regs.DigitalInput20; public Boolean K2IslandBusIsConnectedToGridBus => !_Regs.DigitalInput20;
public Boolean Wago1Status => _Regs.DigitalInput0;
public Boolean Wago2Status => _Regs.DigitalInput1;
public Boolean Wago3Status => _Regs.DigitalInput2;
public Boolean Wago4Status => _Regs.DigitalInput3;
public IEnumerable<Boolean> K3InverterIsConnectedToIslandBus public IEnumerable<Boolean> K3InverterIsConnectedToIslandBus
{ {
get get

View File

@ -489,7 +489,7 @@ public static class Topology
public static DcPowerDevice? CalculateAcDcToDcLink(AmptStatus? pvOnDc, DcDcDevicesRecord? dcDc, AcDcDevicesRecord acDc) public static DcPowerDevice? CalculateAcDcToDcLink(AmptStatus? pvOnDc, DcDcDevicesRecord? dcDc, AcDcDevicesRecord acDc)
{ {
var i = pvOnDc?.Dc.Power; var i = pvOnDc?.Dc.Power;
var k = dcDc?.Dc.Link.Power; // We dont check on the DcDc because this device is mandatory var k = dcDc?.Dc.Link.Power; // We don't check on the DcDc because this device is mandatory
var g = acDc?.Dc.Power; var g = acDc?.Dc.Power;
if (i is null || k is null ) if (i is null || k is null )

View File

@ -1,19 +1,3 @@
/*using InnovEnergy.Lib.Devices.IEM3kGridMeter;
using InnovEnergy.Lib.Protocols.DBus.Protocol.DataTypes;
using InnovEnergy.Lib.Victron.VeDBus;
namespace InnovEnergy.App.SchneiderDriver;
// TODO: Does not compile
public record Signal(Func<Iem3KGridMeterRegisters, object> Source, ObjectPath Path, string Format = "")
{
public VeProperty ToVeProperty(Iem3KGridMeterRegisters status)
{
var value = Source(status);
return new VeProperty(Path, value, string.Format($"{{0:{Format}}}", value));
}
}*/
using InnovEnergy.Lib.Devices.IEM3kGridMeter; using InnovEnergy.Lib.Devices.IEM3kGridMeter;
using InnovEnergy.Lib.Protocols.DBus.Protocol.DataTypes; using InnovEnergy.Lib.Protocols.DBus.Protocol.DataTypes;
@ -56,24 +40,3 @@ namespace InnovEnergy.App.SchneiderDriver
} }
} }
/*namespace InnovEnergy.App.SchneiderDriver
{
public record Signal(Func<Iem3KGridMeterRegisters, object> Source, ObjectPath Path, string Format = "")
{
public VeProperty ToVeProperty(Iem3KGridMeterRegisters status)
{
if (status == null)
{
Console.WriteLine($"Status is null for path: {Path}");
// Return a default VeProperty if status is null
return new VeProperty(Path, default, String.Format($"{{0:{Format}}}", default));
}
var value = Source(status);
return new VeProperty(Path, value, String.Format($"{{0:{Format}}}", value));
}
}
}*/

View File

@ -31,4 +31,11 @@ public class Adam6360DRegisters
[Coil(38)] public Boolean Relay5 { get; set; } [Coil(38)] public Boolean Relay5 { get; set; }
[Coil(39)] public Boolean Relay6 { get; set; } [Coil(39)] public Boolean Relay6 { get; set; }
[Coil(40)] public Boolean Relay7 { get; set; } [Coil(40)] public Boolean Relay7 { get; set; }
[Coil(41)] public Boolean DigitalOutput0 { get; set; }
[Coil(42)] public Boolean DigitalOutput1 { get; set; }
[Coil(43)] public Boolean DigitalOutput2 { get; set; }
[Coil(44)] public Boolean DigitalOutput3 { get; set; }
[Coil(45)] public Boolean DigitalOutput4 { get; set; }
[Coil(46)] public Boolean DigitalOutput5 { get; set; }
} }