Addexport limitation Growatt and fix the udp check

This commit is contained in:
atef 2026-04-10 15:21:57 +02:00
parent d34b226b6e
commit 9d4d87ce27
4 changed files with 124 additions and 36 deletions

View File

@ -9,24 +9,41 @@ namespace InnovEnergy.App.GrowattCommunication.MiddlewareClasses;
public static class MiddlewareAgent
{
private static UdpClient _udpListener = null!;
private static UdpClient _udpListener = null!;
private static IPAddress? _controllerIpAddress;
private static EndPoint? _endPoint;
private static EndPoint? _endPoint;
public static void InitializeCommunicationToMiddleware()
public static bool InitializeCommunicationToMiddleware()
{
_controllerIpAddress = FindVpnIp();
if (Equals(IPAddress.None, _controllerIpAddress))
try
{
Console.WriteLine("There is no VPN interface, exiting...");
_controllerIpAddress = FindVpnIp();
if (Equals(IPAddress.None, _controllerIpAddress))
{
Console.WriteLine("There is no VPN interface.");
_udpListener = null;
return false;
}
const int udpPort = 9000;
_endPoint = new IPEndPoint(_controllerIpAddress, udpPort);
_udpListener?.Close();
_udpListener?.Dispose();
_udpListener = new UdpClient();
_udpListener.Client.Blocking = false;
_udpListener.Client.Bind(_endPoint);
Console.WriteLine($"UDP listener bound to {_endPoint}");
return true;
}
catch (Exception ex)
{
Console.WriteLine($"Failed to initialize middleware communication: {ex}");
_udpListener = null;
return false;
}
const Int32 udpPort = 9000;
_endPoint = new IPEndPoint(_controllerIpAddress, udpPort);
_udpListener = new UdpClient();
_udpListener.Client.Blocking = false;
_udpListener.Client.Bind(_endPoint);
}
private static IPAddress FindVpnIp()
@ -50,40 +67,92 @@ public static class MiddlewareAgent
return IPAddress.None;
}
public static Configuration? SetConfigurationFile()
{
if (_udpListener.Available > 0)
try
{
// Ensure listener is initialized
if (_udpListener == null)
{
Console.WriteLine("UDP listener not initialized, trying to initialize...");
InitializeCommunicationToMiddleware();
if (_udpListener == null)
{
Console.WriteLine("Failed to initialize UDP listener.");
return null;
}
}
// Check if data is available
if (_udpListener.Available <= 0)
return null;
IPEndPoint? serverEndpoint = null;
var replyMessage = "ACK";
var replyData = Encoding.UTF8.GetBytes(replyMessage);
var udpMessage = _udpListener.Receive(ref serverEndpoint);
var message = Encoding.UTF8.GetString(udpMessage);
var message = Encoding.UTF8.GetString(udpMessage);
Console.WriteLine($"Received raw UDP message from {serverEndpoint}: {message}");
var config = JsonSerializer.Deserialize<Configuration>(message);
if (config != null)
{
Console.WriteLine($"Received a configuration message: " +
"MinimumSoC is " + config.MinimumSoC + " and operating priorty is " +config.OperatingPriority + "Number of batteries is " + config.BatteriesCount
+ "MaximumChargingCurrent is " + config.MaximumChargingCurrent + "MaximumDischargingCurrent " + config.MaximumDischargingCurrent + " Control permission is" + config.ControlPermission );
// Send the reply to the sender's endpoint
Console.WriteLine(
$"Received a configuration message:\n" +
$"MinimumSoC: {config.MinimumSoC}\n" +
$"OperatingPriority: {config.OperatingPriority}\n" +
$"Number of batteries: {config.BatteriesCount}\n" +
$"Maximum Charging current: {config.MaximumChargingCurrent}\n" +
$"Maximum Discharging current: {config.MaximumDischargingCurrent}\n" +
$"ControlPermission: {config.ControlPermission}"
);
// Send ACK
var replyMessage = "ACK";
var replyData = Encoding.UTF8.GetBytes(replyMessage);
_udpListener.Send(replyData, replyData.Length, serverEndpoint);
Console.WriteLine($"Replied to {serverEndpoint}: {replyMessage}");
return config;
}
else
{
Console.WriteLine("Received UDP message but failed to deserialize Configuration.");
return null;
}
}
if (_endPoint != null && !_endPoint.Equals(_udpListener.Client.LocalEndPoint as IPEndPoint))
catch (SocketException ex)
{
Console.WriteLine("UDP address has changed, rebinding...");
InitializeCommunicationToMiddleware();
}
return null;
}
Console.WriteLine($"Socket error in SetConfigurationFile: {ex}");
// Recover by reinitializing
try
{
_udpListener?.Close();
_udpListener?.Dispose();
}
catch
{
// ignored
}
_udpListener = null;
InitializeCommunicationToMiddleware();
return null;
}
catch (JsonException ex)
{
Console.WriteLine($"JSON deserialization error: {ex}");
return null;
}
catch (Exception ex)
{
Console.WriteLine($"Unexpected error in SetConfigurationFile: {ex}");
return null;
}
}
}

View File

@ -6,12 +6,13 @@ username='inesco'
root_password='Sodistore0918425'
release_flag_file="./bin/Release/$dotnet_version/linux-arm64/publish/.release.flag"
DOTNET="/snap/dotnet-sdk_60/current/dotnet"
set -e
echo -e "\n============================ Build ============================\n"
dotnet publish \
"$DOTNET" publish \
./GrowattCommunication.csproj \
-p:PublishTrimmed=false \
-c Release \

View File

@ -141,6 +141,20 @@ public partial class WITGrowatRecord
//set => _PowerFactor = value;
}
public UInt16 ExportLimitationEnabled
{
get => _ExportLimitationEnabled;
set => _ExportLimitationEnabled = value;
}
public Int16 ExportLimitationPowerRate
{
get => _ExportLimitationPowerRate;
set => _ExportLimitationPowerRate = value;
}
public UInt16 EmsCommunicationFailureTime
{

View File

@ -165,7 +165,11 @@ public partial class WITGrowatRecord
//[HoldingRegister<UInt32>(30152, writable: true)] private UInt16 _Reserved11; //
[HoldingRegister(30154, writable: true)] private UInt16 _ActivePowerPercent; // Limit percentage: [0, 100]; Default: 100; takes the smaller value of 30151 and 30154 as actual active limit; Not stored
[HoldingRegister(30162)] private UInt16 _PowerFactor; // [0, 2000] [18000, 20000]; Default: 20000; Actual PF = (Register Value - 10000)
[HoldingRegister(30162)] private UInt16 _PowerFactor; // [0, 2000] [18000, 20000]; Default: 20000; Actual PF = (Register Value - 10000)
[HoldingRegister(30200, writable : true)] private UInt16 _ExportLimitationEnabled; // // 0: not enabled // 1: single machine Export Limitation enable
[HoldingRegister(30201, writable : true)] private Int16 _ExportLimitationPowerRate; // [-100100] // Default value: 0 Positive value is backflow, negative value is fair current
[HoldingRegister(30203, writable : true)] private UInt16 _EmsCommunicationFailureTime; // [1,300] TODO to 30
[HoldingRegister(30204, writable : true)] private Boolean _EnableEmsCommunicationFailureTime; // 0: disabled, 1 = enabled we should not enable this the naming is not correct
[HoldingRegister(30300)] private UInt16 _BatteryClusterIndex; // [0..3]