Addexport limitation Growatt and fix the udp check
This commit is contained in:
parent
d34b226b6e
commit
9d4d87ce27
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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; // [-100,100] // 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]
|
||||
|
|
|
|||
Loading…
Reference in New Issue