Procházet zdrojové kódy

Merge branch 'Master_TIN02_develop' of http://git.jetplasma-oa.com/Jet/Minics into Master_TIN02_develop

SenGao před 3 týdny
rodič
revize
36657ac665

+ 2 - 0
.gitignore

@@ -45,3 +45,5 @@
 /Tools/UserTool/obj
 /Tools/ToMcFile/obj
 /Tools/OnlineLogViewer/obj
+/CommunicationProtocols/AdsCommunicatorNet8/bin/Debug/net8.0
+/CommunicationProtocols/AdsCommunicatorNet8/obj

+ 294 - 0
CommunicationProtocols/AdsCommunicatorNet8/AdsCommunicator.cs

@@ -0,0 +1,294 @@
+using Log;
+using ProtocalGeneral;
+using System.Collections.Concurrent;
+using TwinCAT.Ads.SumCommand;
+using TwinCAT.TypeSystem;
+
+namespace AdsCommunicatorNet8;
+
+//this Implementation has removed notification function, only get value and set value available
+public class AdsCommunicator(ILog log):IDisposable
+{
+    private bool _isConnected;
+    private string? _netID = null;
+    private int _port = 0;
+
+
+    private AdsClient? _adsClient;
+    private List<string[]>? _adsCsvInfo;
+    private ITcpConnectNority? _connectionNotify;
+    private bool disposedValue;
+    private readonly ConcurrentDictionary<string, IAdsSymbol> _symbols = [];
+
+
+    public bool IsConnected { get { return _isConnected; } }
+
+    public bool Initialize(ITcpConnectNority connectionNotify)
+    {
+        if (this._adsClient is not null)
+            return false;
+
+
+        this._adsClient = new AdsClient();
+        this._adsCsvInfo = [];
+        this._connectionNotify = connectionNotify;
+
+        return true;
+    }
+
+    public bool Open(string netID, int port, int retry)
+    {
+        log?.Info($"Try Open {netID} {port}");
+        if (this._adsClient is null)
+        {
+            log?.Warning("Not initialized before Open");
+            return false;
+        }
+
+        if (this._adsClient.IsConnected)
+        {
+            log?.Warning($"Ads {netID} {port} already connected");
+            return false;
+        }
+
+        this._adsClient.ConnectionStateChanged += AdsClient_ConnectionStateChanged;
+
+
+        for (int i = 1; i <= retry; i++)
+        {
+            log?.Info($"Try Connected {i}");
+
+            try
+            {
+                this._adsClient.Connect(netID, port);
+                if (this._adsClient.TryReadState(out _) == AdsErrorCode.NoError)
+                    break;
+            }
+            catch
+            {
+
+            }
+
+            if (i == retry)
+            {
+                log?.Error($"Reach Max Retry {i}, connect failed");
+                return false;
+            }
+            Thread.Sleep(300);
+
+        }
+
+        this._netID = netID;
+        this._port = port;
+
+        log?.Info($"Connect success");
+        this._isConnected = true;
+        return true;
+    }
+
+    public bool ReConnect()
+    {
+        if (string.IsNullOrEmpty(this._netID) || this._port == 0)
+            return false;
+        this._adsClient ??= new();
+        if (this._adsClient.IsConnected)
+            return true;
+
+        for (; ; )
+        {
+            log?    .Info($"Try ReConnected");
+
+            try
+            {
+                this._adsClient.Connect(_netID, _port);
+                if (this._adsClient.TryReadState(out _) == AdsErrorCode.NoError)
+                    break;
+            }
+            catch
+            {
+                Thread.Sleep(300);
+            }
+        }
+
+        return true;
+    }
+
+    public bool GetValue<T>(string symbolName, out T? value)
+    {
+        value = default;
+
+        if (string.IsNullOrEmpty(symbolName))
+        {
+            log?.Warning("Symbol Empty");
+            return false;
+        }
+
+        log?.Info($"Try get value {symbolName}");
+
+        if (this._adsClient is null)
+        {
+            log?    .Error("PLC not connected");
+            return false;
+        }
+
+        if (!this._symbols.TryGetValue(symbolName, out IAdsSymbol? adsSymbol) || adsSymbol is null)
+        {
+            log?.Info($"{symbolName} not Created before try create symbol");
+            if (this._adsClient.TryReadSymbol(symbolName, out adsSymbol) != AdsErrorCode.NoError || adsSymbol is null)
+            {
+                log?.Error($"{symbolName} not exist in PLC");
+                return false;
+            }
+
+            this._symbols[symbolName] = adsSymbol;
+        }
+
+        try
+        {
+            value = (T)this._adsClient.ReadValue(adsSymbol);
+            log?.Info($"{symbolName} value {value}");
+        }
+        catch (Exception ex)
+        {
+            log?.Error($"{symbolName} Read failed: {ex.Message}");
+            return false;
+        }
+
+        return true;
+    }
+
+    public bool SetValue<T>(string symbolName, T value) where T : notnull
+    {
+        if (string.IsNullOrEmpty(symbolName))
+        {
+            log?.Warning("Set Value Symbol empty");
+            return false;
+        }
+
+        log?.Info($"Try set value {symbolName}");
+
+        if (this._adsClient is null)
+        {
+            log?.Error("PLC not connected");
+            return false;
+        }
+
+        if (value is null)
+        {
+            log?.Warning("Value Empty");
+            return false;
+        }
+
+        log?.Info($"Value {value}");
+
+        if (!this._symbols.TryGetValue(symbolName, out IAdsSymbol? adsSymbol) || adsSymbol is null)
+        {
+            log?.Info($"{symbolName} not Created before try create symbol");
+            if (this._adsClient.TryReadSymbol(symbolName, out adsSymbol) != AdsErrorCode.NoError || adsSymbol is null)
+            {
+                log?.Error($"{symbolName} not exist in PLC");
+                return false;
+            }
+
+            this._symbols[symbolName] = adsSymbol;
+        }
+
+        try
+        {
+            this._adsClient.WriteValue(adsSymbol, value);
+            log?.Info($"Set {symbolName} value {value} succeeded");
+        }
+        catch (Exception ex)
+        {
+            log?.Error($"{symbolName} Set failed: {ex.Message}");
+            return false;
+        }
+
+        return true;
+    }
+
+    public bool SetBatchValue(IEnumerable<string> symbolCollection, IList<object> valueCollection)
+    {
+        if (this._adsClient is null)
+            return false;
+
+        if (symbolCollection is null || valueCollection is null)
+            return false;
+
+        if (symbolCollection.Count() != symbolCollection.Count())
+            return false;
+
+        List<ISymbol> symbols = [];
+        foreach (var item in symbolCollection)
+        {
+            if (!this._symbols.TryGetValue(item, out IAdsSymbol? symbol) || symbol is null)
+            {
+                log?.Warning($"BatchSend: {item} not Registered before");
+                return false;
+            }
+
+            symbols.Add(symbol);
+        }
+
+        SumSymbolWrite writes = new(this._adsClient, symbols);
+        try
+        {
+            writes.Write([.. valueCollection]);
+        }
+        catch (Exception ex)
+        {
+            log?.Warning(ex.Message);
+            return false;
+        }
+
+        return true;
+    }
+
+    private void AdsClient_ConnectionStateChanged(object? sender, TwinCAT.ConnectionStateChangedEventArgs e)
+    {
+        if (this._adsClient is null)
+            return;
+
+        log?.Info($"{e.NewState} {this._adsClient.Address.NetId} {this._adsClient.Address.Port}");
+
+        switch (e.NewState)
+        {
+            case TwinCAT.ConnectionState.Connected:
+                this._isConnected = true;
+                this._connectionNotify?.Connect(this._adsClient.Address.NetId.ToString(), this._adsClient.Address.Port);
+                break;
+            case TwinCAT.ConnectionState.Disconnected:
+            case TwinCAT.ConnectionState.Lost:
+            default:
+                this._isConnected = false;
+                this._connectionNotify?.DisConnect(this._adsClient.Address.NetId.ToString(), this._adsClient.Address.Port);
+                break;
+        }
+    }
+
+
+    #region Dispose
+    protected virtual void Dispose(bool disposing)
+    {
+        log?.Info("Disposing AdsCommunication");
+        if (!disposedValue)
+        {
+            if (disposing)
+            {
+                this._adsClient?.Dispose();
+                this._adsClient = null;
+                this._adsCsvInfo?.Clear();
+            }
+
+            disposedValue = true;
+        }
+    }
+
+     void IDisposable.Dispose()
+    {
+        Dispose(disposing: true);
+        GC.SuppressFinalize(this);
+    }
+
+    #endregion
+}

+ 18 - 0
CommunicationProtocols/AdsCommunicatorNet8/AdsCommunicatorNet8.csproj

@@ -0,0 +1,18 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Beckhoff.TwinCAT.Ads" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\..\Log\Log\Log.csproj" />
+    <ProjectReference Include="..\ProtocalGeneral\ProtocalGeneral.csproj" />
+  </ItemGroup>
+
+</Project>

+ 6 - 0
CommunicationProtocols/AdsCommunicatorNet8/Properties/_global.cs

@@ -0,0 +1,6 @@
+global using AdsInterface;
+global using AdsInterface.Data;
+global using System.Collections.ObjectModel;
+global using TwinCAT.Ads;
+global using TwinCAT.Ads.TypeSystem;
+global using UniversalNetFrame451;

+ 0 - 7
CommunicationProtocols/TwinCatADS/Class1.cs

@@ -1,7 +0,0 @@
-namespace TwinCatADS
-{
-    public class Class1
-    {
-
-    }
-}

+ 0 - 9
CommunicationProtocols/TwinCatADS/TwinCatADS.csproj

@@ -1,9 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <TargetFramework>net8.0</TargetFramework>
-    <ImplicitUsings>enable</ImplicitUsings>
-    <Nullable>enable</Nullable>
-  </PropertyGroup>
-
-</Project>

+ 1 - 0
Directory.Packages.props

@@ -3,6 +3,7 @@
     <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
   </PropertyGroup>
   <ItemGroup>
+    <PackageVersion Include="Beckhoff.TwinCAT.Ads" Version="6.2.485" />
     <PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0" />
     <PackageVersion Include="DH.NModbus" Version="3.91.2024.1031" />
     <PackageVersion Include="EasyModbusCore" Version="1.0.0" />

+ 7 - 7
Minics.sln

@@ -87,10 +87,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModBusTcp", "CommunicationP
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProtocalGeneral", "CommunicationProtocols\ProtocalGeneral\ProtocalGeneral.csproj", "{55EC57EB-3DA4-4289-803F-4661A6EAE1B9}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TwinCatADS", "CommunicationProtocols\TwinCatADS\TwinCatADS.csproj", "{81EA7F4C-9379-4314-B8DC-F907F86D8535}"
-EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AlarmInfoServerSim", "Tools\AlarmInfoServerSim\AlarmInfoServerSim.csproj", "{EF692000-6C78-4EA6-81BF-58371231510E}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdsCommunicatorNet8", "CommunicationProtocols\AdsCommunicatorNet8\AdsCommunicatorNet8.csproj", "{D784466C-1F32-4621-1B3D-D1AC0CC08709}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -221,14 +221,14 @@ Global
 		{55EC57EB-3DA4-4289-803F-4661A6EAE1B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{55EC57EB-3DA4-4289-803F-4661A6EAE1B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{55EC57EB-3DA4-4289-803F-4661A6EAE1B9}.Release|Any CPU.Build.0 = Release|Any CPU
-		{81EA7F4C-9379-4314-B8DC-F907F86D8535}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{81EA7F4C-9379-4314-B8DC-F907F86D8535}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{81EA7F4C-9379-4314-B8DC-F907F86D8535}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{81EA7F4C-9379-4314-B8DC-F907F86D8535}.Release|Any CPU.Build.0 = Release|Any CPU
 		{EF692000-6C78-4EA6-81BF-58371231510E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{EF692000-6C78-4EA6-81BF-58371231510E}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{EF692000-6C78-4EA6-81BF-58371231510E}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{EF692000-6C78-4EA6-81BF-58371231510E}.Release|Any CPU.Build.0 = Release|Any CPU
+		{D784466C-1F32-4621-1B3D-D1AC0CC08709}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{D784466C-1F32-4621-1B3D-D1AC0CC08709}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{D784466C-1F32-4621-1B3D-D1AC0CC08709}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{D784466C-1F32-4621-1B3D-D1AC0CC08709}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -261,8 +261,8 @@ Global
 		{85D48105-88EC-4B80-B394-76DB988F6DD4} = {165A518A-753D-4062-A100-9367AF27F900}
 		{6B500EDB-EB90-4AA6-A0EB-90241292D370} = {165A518A-753D-4062-A100-9367AF27F900}
 		{55EC57EB-3DA4-4289-803F-4661A6EAE1B9} = {165A518A-753D-4062-A100-9367AF27F900}
-		{81EA7F4C-9379-4314-B8DC-F907F86D8535} = {165A518A-753D-4062-A100-9367AF27F900}
 		{EF692000-6C78-4EA6-81BF-58371231510E} = {2783D72A-0926-427D-B70D-5F3F5FA757FC}
+		{D784466C-1F32-4621-1B3D-D1AC0CC08709} = {165A518A-753D-4062-A100-9367AF27F900}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {2E8CB4A6-1AFA-4CB2-BA42-1BAFC71AD68B}

+ 15 - 11
Test/ConfigConverter.cs

@@ -10,20 +10,24 @@ namespace Test;
 
 internal class ConfigConverter
 {
-    public void Convert()
+    public void Convert(string basePath)
     {
-        //Hardwares hardwares = new();
+        if (string.IsNullOrEmpty(basePath))
+            return;
+        string localBase =Path.Combine( System.Environment.CurrentDirectory,"Settings");
 
-        //HardwareFileLoader hardwareFileLoader = new(hardwares);
-        //hardwareFileLoader.Load(@"D:\Settings\Hardwares");
-        //hardwareFileLoader.Save(@"D:\NewJson\Hardwares");
 
-        //HardwareAddress hardwareAddress = new HardwareAddress();
-        //AddressFileLoader addressFileLoader = new(hardwareAddress);
-        //addressFileLoader.LoadPLC(@"E:\Download\Settings\Settings\PLCIOList",@"E:\Download\Settings\Settings\PLCIOList\PLCChannel");
-        //addressFileLoader.SavePLC(@"D:\NewJson\PLCIOList", @"D:\NewJson\PLCIOList\PLCChannel");
-        //addressFileLoader.Load(@"E:\Download\Settings\Settings\IOList");
-        //addressFileLoader.Save(@"D:\NewJson\IOList");
+        Hardwares hardwares = new();
+        HardwareFileLoader hardwareFileLoader = new(hardwares);
+        hardwareFileLoader.Load(Path.Combine(basePath, "Hardwares"));
+        hardwareFileLoader.Save(Path.Combine(localBase, "Hardwares"));
+
+        HardwareAddress hardwareAddress = new HardwareAddress();
+        AddressFileLoader addressFileLoader = new(hardwareAddress);
+        addressFileLoader.LoadPLC(Path.Combine(basePath, "PLCIOList"), Path.Combine(basePath, "PLCIOList", "PLCChannel"));
+        addressFileLoader.SavePLC(Path.Combine(localBase, "PLCIOList"), Path.Combine(localBase, "PLCIOList", "PLCChannel"));
+        addressFileLoader.Load(Path.Combine(basePath, "IOList"));
+        addressFileLoader.Save(Path.Combine(localBase, "IOList"));
 
     }
 }

+ 2 - 3
Test/Program.cs

@@ -46,8 +46,8 @@ internal class Program
         test.RunOnce();
         Thread.Sleep(-1);
 
-        ConfigConverter converter = new();
-        converter.Convert();
+        //ConfigConverter converter = new();
+        //converter.Convert(@"E:\Download\Settings\Settings");
     }
 }
 
@@ -178,7 +178,6 @@ public class TestClass : IRTMini8Provider
     public void ChannelAlarmNotify(ST_ALARM alarm)
     {
         Console.WriteLine($"Alarm Mini8 {alarm.Mini8Index}-{alarm.ChannelIndex:00} {alarm.PV:000.00} {alarm.Caps:000.00} {alarm.Floor:000.00} {alarm.AlarmType}");
-
     }
 
     public void Mini8ConnectNotify(byte mini8Index)