首次提交:添加src文件夹代码

This commit is contained in:
2026-02-27 14:02:43 +08:00
commit d330cfbca7
4184 changed files with 5546478 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Cowain.Bake.Common.Core;
using Cowain.Bake.Communication.FTP;
using Cowain.Bake.Communication.MOM;
using Cowain.Bake.Communication.PLC;
using Cowain.Bake.Communication.Scan;
using Cowain.Bake.Communication.Sokects;
using Prism.Ioc;
using Prism.Modularity;
using Unity;
namespace Cowain.Bake.Communication
{
[Module(ModuleName = "CommunicationModule")]
public class CommunicationModule : IModule
{
public void OnInitialized(IContainerProvider containerProvider) //IContainerProvider
{
containerProvider.Resolve<PLCManage>();
containerProvider.Resolve<ScanCodeManage>();
//containerProvider.Resolve<HttpServer>();
//containerProvider.Resolve<FtpHelper>();
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<PLCManage>();
containerRegistry.RegisterSingleton<ScanCodeManage>();
containerRegistry.RegisterSingleton<HttpServer>();
containerRegistry.RegisterSingleton<GenericFun>();
//containerRegistry.Register<FtpHelper>();
//containerRegistry.Register<FTPUpload>();
//containerRegistry.Register<FTPElapsedDelete>();
containerRegistry.RegisterSingleton<MESProcess>();
containerRegistry.RegisterSingleton<PLCBlockingCollection>();
}
}
}

View File

@@ -0,0 +1,380 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{152AAF38-8F84-4EBB-93C0-15C71C2B85EB}</ProjectGuid>
<OutputType>library</OutputType>
<RootNamespace>Cowain.Bake.Communication</RootNamespace>
<AssemblyName>Cowain.Bake.Communication</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<LangVersion>8.0</LangVersion>
<!-- 将此版本号设置为 8.0 或更高 -->
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Cognex.DataMan.SDK.Discovery.PC">
<HintPath>..\Libs\Cognex.DataMan.SDK.Discovery.PC.dll</HintPath>
</Reference>
<Reference Include="Cognex.DataMan.SDK.PC">
<HintPath>..\Libs\Cognex.DataMan.SDK.PC.dll</HintPath>
</Reference>
<Reference Include="Cognex.DataMan.SDK.Utils.PC">
<HintPath>..\Libs\Cognex.DataMan.SDK.Utils.PC.dll</HintPath>
</Reference>
<Reference Include="Communication">
<HintPath>..\Libs\Communication.dll</HintPath>
</Reference>
<Reference Include="Cowain.Bake.BLL">
<HintPath>..\Cowain.Bake.BLL\bin\Debug\Cowain.Bake.BLL.dll</HintPath>
</Reference>
<Reference Include="Cowain.Bake.Common">
<HintPath>..\Cowain.Bake.Common\bin\Debug\Cowain.Bake.Common.dll</HintPath>
</Reference>
<Reference Include="Cowain.Bake.Model">
<HintPath>..\Cowain.Bake.Model\bin\Debug\Cowain.Bake.Model.dll</HintPath>
</Reference>
<Reference Include="FluentFTP, Version=46.0.2.0, Culture=neutral, PublicKeyToken=f4af092b1d8df44f, processorArchitecture=MSIL">
<HintPath>..\packages\FluentFTP.46.0.2\lib\net472\FluentFTP.dll</HintPath>
</Reference>
<Reference Include="HandyControl, Version=3.5.1.0, Culture=neutral, PublicKeyToken=45be8712787a1e5b, processorArchitecture=MSIL">
<HintPath>..\packages\HandyControl.3.5.1\lib\net472\HandyControl.dll</HintPath>
</Reference>
<Reference Include="HslCommunication">
<HintPath>..\Libs\HslCommunication.dll</HintPath>
</Reference>
<Reference Include="Keyence.AutoID.SDK">
<HintPath>..\Libs\Keyence.AutoID.SDK.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.7.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.HashCode, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Libs\Microsoft.Bcl.HashCode.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CodeAnalysis, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.Common.2.0.0\lib\netstandard1.3\Microsoft.CodeAnalysis.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CodeAnalysis.CSharp, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.CSharp.2.0.0\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CodeAnalysis.CSharp.Scripting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.CSharp.Scripting.2.0.0\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.Scripting.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CodeAnalysis.Scripting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.Scripting.Common.2.0.0\lib\netstandard1.3\Microsoft.CodeAnalysis.Scripting.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Abstractions">
<HintPath>..\Libs\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Xaml.Behaviors, Version=1.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Xaml.Behaviors.Wpf.1.1.31\lib\net45\Microsoft.Xaml.Behaviors.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="Opc.Ua.Bindings.Https">
<HintPath>..\Libs\Opc.Ua.Bindings.Https.dll</HintPath>
</Reference>
<Reference Include="Opc.Ua.Client">
<HintPath>..\Libs\Opc.Ua.Client.dll</HintPath>
</Reference>
<Reference Include="Opc.Ua.ClientControls">
<HintPath>..\Libs\Opc.Ua.ClientControls.dll</HintPath>
</Reference>
<Reference Include="Opc.Ua.Configuration">
<HintPath>..\Libs\Opc.Ua.Configuration.dll</HintPath>
</Reference>
<Reference Include="Opc.Ua.Core">
<HintPath>..\Libs\Opc.Ua.Core.dll</HintPath>
</Reference>
<Reference Include="Opc.Ua.Security.Certificates, Version=1.5.374.0, Culture=neutral, PublicKeyToken=bfa7a73c5cf4b6e8, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Libs\Opc.Ua.Security.Certificates.dll</HintPath>
</Reference>
<Reference Include="Opc.Ua.Server">
<HintPath>..\Libs\Opc.Ua.Server.dll</HintPath>
</Reference>
<Reference Include="OpcUaHelper, Version=2.1.3.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Libs\OpcUaHelper.dll</HintPath>
</Reference>
<Reference Include="Prism">
<HintPath>..\Libs\Prism.dll</HintPath>
</Reference>
<Reference Include="Prism.Unity.Wpf">
<HintPath>..\Libs\Prism.Unity.Wpf.dll</HintPath>
</Reference>
<Reference Include="Prism.Wpf">
<HintPath>..\Libs\Prism.Wpf.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.AppContext, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.AppContext.4.3.0\lib\net463\System.AppContext.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Collections.Specialized, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Specialized.4.3.0\lib\net46\System.Collections.Specialized.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Configuration" />
<Reference Include="System.Console, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Console.4.3.0\lib\net46\System.Console.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Diagnostics.FileVersionInfo, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Diagnostics.FileVersionInfo.4.3.0\lib\net46\System.Diagnostics.FileVersionInfo.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Diagnostics.StackTrace, Version=4.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Diagnostics.StackTrace.4.3.0\lib\net46\System.Diagnostics.StackTrace.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.IO, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.IO.4.3.0\lib\net462\System.IO.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.IO.FileSystem, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.IO.FileSystem.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Linq, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Linq.4.3.0\lib\net463\System.Linq.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Linq.Expressions, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Linq.Expressions.4.3.0\lib\net463\System.Linq.Expressions.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Net.NameResolution, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Net.NameResolution.4.3.0\lib\net46\System.Net.NameResolution.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Security, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Net.Security.4.3.0\lib\net46\System.Net.Security.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Sockets, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Reflection, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Runtime, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Extensions, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.Extensions.4.3.0\lib\net462\System.Runtime.Extensions.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Runtime.InteropServices, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.InteropServices.4.3.0\lib\net463\System.Runtime.InteropServices.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Security.Cryptography.Algorithms, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net463\System.Security.Cryptography.Algorithms.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Text.Encoding.CodePages, Version=9.0.0.6, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Encoding.CodePages.9.0.6\lib\net462\System.Text.Encoding.CodePages.dll</HintPath>
</Reference>
<Reference Include="System.Text.Encodings.Web, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Encodings.Web.7.0.0\lib\net462\System.Text.Encodings.Web.dll</HintPath>
</Reference>
<Reference Include="System.Text.Json, Version=7.0.0.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Json.7.0.2\lib\net462\System.Text.Json.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Thread, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Thread.4.3.0\lib\net46\System.Threading.Thread.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml.ReaderWriter, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.XmlDocument, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.XPath, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.XPath.XDocument, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Xml.XPath.XDocument.4.3.0\lib\net46\System.Xml.XPath.XDocument.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="Unity.Abstractions, Version=5.11.7.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\packages\Unity.Abstractions.5.11.7\lib\net47\Unity.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Unity.Container, Version=5.11.11.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\packages\Unity.Container.5.11.11\lib\net47\Unity.Container.dll</HintPath>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<Compile Include="CommunicationModule.cs" />
<Compile Include="GenericFun.cs" />
<Compile Include="Interface\IScanCodeBase.cs" />
<Compile Include="FTP\FTPElapsedDelete.cs" />
<Compile Include="FTP\FTPUpload.cs" />
<Compile Include="Interface\IPLCDevice.cs" />
<Compile Include="Interface\IPLCService.cs" />
<Compile Include="MOM\HttpClientHelper.cs" />
<Compile Include="MOM\MESProcess.cs" />
<Compile Include="Models\ExOperateResult.cs" />
<Compile Include="PLC\PLCBlockingCollection.cs" />
<Compile Include="PLC\PLC_OpcUaClient.cs" />
<Compile Include="PLC\PLCBase.cs" />
<Compile Include="PLC\PLCManage.cs" />
<Compile Include="PLC\PLC_ModbusTcp.cs" />
<Compile Include="PLC\PLC_OmronFins.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="Scan\Cognex.cs" />
<Compile Include="Scan\Honeywell.cs" />
<Compile Include="Scan\Keyence.cs" />
<Compile Include="Scan\ScanCodeManage.cs" />
<Compile Include="FTP\FTPClient.cs" />
<Compile Include="Sokects\HttpServer.cs" />
<Compile Include="Sokects\TcpSokectClient.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="app.config" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.Analyzers.dll" />
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<WCFMetadata Include="Connected Services\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectView>ProjectFiles</ProjectView>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,193 @@
using Cowain.Bake.Common.Core;
using FluentFTP;
using System;
using System.IO;
namespace Cowain.Bake.Communication.FTP
{
//现在是的是短连接,即上传完就关闭; 后期如果有效率上的要求,要改成长连接,就是过程中不关闭连接
//建立好连接700毫秒
//关闭连接90毫秒
//全部都是远程操作
public class FtpHelper
{
#region
public FtpClient ftpClient { get; set; } ///
public string IpAddr { get; set; } /// IP地址
public string RelatePath { get; set; } /// 相对路径
public int Port { get; set; } /// 端口号
public string UserName { get; set; } /// 用户名
public string Password { get; set; } /// 密码
public bool IsConnected { get; set; } = false;
//https://blog.csdn.net/fengershishe/article/details/129140618
public FtpHelper(string ipAddr, int port, string userName, string password, string relatePath = "")
{
this.IpAddr = ipAddr;
this.Port = port;
this.UserName = userName;
this.Password = password;
//this.RelatePath = relatePath;
}
#endregion
public bool Connect()
{
try
{
Close();
//using (var ftpClient = new FtpClient(this.IpAddr, this.UserName, this.Password, this.Port))
ftpClient = new FtpClient(this.IpAddr, this.Port);
ftpClient.Connect(); // 连接到FTP服务器
}
catch (Exception ex)
{
LogHelper.Instance.Error($"Ftp Connect {ex.Message}");
IsConnected = false;
return false;
}
IsConnected = ftpClient.IsConnected;
return IsConnected;
}
bool IsConnect()
{
if (null == ftpClient || !ftpClient.IsConnected || !IsConnected)
{
Connect();
}
return IsConnected;
}
public void Close()
{
if (null != ftpClient)
{
ftpClient.Disconnect();
ftpClient.Dispose();
ftpClient = null;
}
}
~FtpHelper()
{
Close();
}
#region
public FtpListItem[] ListDir()
{
FtpListItem[] lists = null;
if (IsConnect())
{
ftpClient.SetWorkingDirectory(this.RelatePath);
lists = ftpClient.GetListing(); //当前路径下,返回所有文件
}
return lists;
}
// 上传文件
public bool UpLoad(string srcFilePath, string descPath)
{
string descFilePath = null;
try
{
if (IsConnect())
{
string fileName = Path.GetFileName(srcFilePath);
char lastChar = descPath[descPath.Length - 1];
if ('\\' == lastChar
|| '/' == lastChar)
{
descFilePath = descPath + fileName; //descPath, 最后一个,是"/"
}
else
{
descFilePath = descPath + "/" + fileName; //descPath, 最后一个,是"/"
}
FtpStatus result = ftpClient.UploadFile(srcFilePath, descFilePath); // ("local/file.txt", "remote/file.txt");
return FtpStatus.Success == result ? true : false;
}
}
catch (Exception ex)
{
IsConnected = false;
LogHelper.Instance.Error($"Ftp UpLoad {ex.Message}");
}
return false;
}
///创建目录(远程创建)
private bool CheckDirIsExists(string dir)
{
bool flag = false;
try
{
if (IsConnect())
{
ftpClient.SetWorkingDirectory(this.RelatePath);
flag = ftpClient.DirectoryExists(dir);
if (!flag)
{
flag = ftpClient.CreateDirectory(dir); //client.CreateDirectory("remote/directory");
return flag;
}
}
return flag;
}
catch (Exception ex)
{
IsConnected = false;
LogHelper.Instance.Error($"Ftp CheckDirIsExists {ex.Message}");
}
return false;
}
public bool DeleteFile(string dir)
{
try
{
if (IsConnect())
{
ftpClient.SetWorkingDirectory(this.RelatePath);
ftpClient.DeleteFile(dir);
return true;
}
}
catch (Exception ex)
{
IsConnected = false;
LogHelper.Instance.Error($"Ftp DeleteFile {ex.Message}");
}
return false;
}
public bool DownloadFile(string localAddress, string remoteAddress)
{
try
{
if (IsConnect())
{
ftpClient.SetWorkingDirectory(this.RelatePath);
FtpStatus status = ftpClient.DownloadFile(localAddress, remoteAddress);
return status == FtpStatus.Success ? true : false;
}
}
catch (Exception ex)
{
IsConnected = false;
LogHelper.Instance.Error($"Ftp DownloadFile {ex.Message}");
}
return false;
}
#endregion
}
}

View File

@@ -0,0 +1,79 @@
using Cowain.Bake.Common;
using Cowain.Bake.Common.Core;
using System;
using System.IO;
using System.Timers;
using Unity;
namespace Cowain.Bake.Communication.FTP
{
//定时删除文件
public class FTPElapsedDelete
{
Timer timer;
string _deleteFilePath;
int _intervalDays;
public string Name { get; set; }
public IUnityContainer _unityContainer { get; set; }
public FTPElapsedDelete(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
public void Start(string filePath, int intervalDays)
{
_deleteFilePath = filePath;
_intervalDays = intervalDays;
CreateTimer();
}
void CreateTimer()
{
// 创建定时器并设置时间间隔为一天
//timer = new Timer();
timer = new Timer(TimeSpan.FromHours(12).TotalMilliseconds); //一天执行二次删除,一次就够了,怕晚上不上班
//timer.Interval = 10 * 1000; // 一个小时
timer.Elapsed += TimerElapsedDeleteFiles;
timer.Start();
}
public void Stop()
{
if (timer != null)
{
timer.Stop();
timer.Elapsed -= TimerElapsedDeleteFiles;
timer.Dispose();
timer = null;
}
}
//可配置定期删除日志文件
void TimerElapsedDeleteFiles(object sender, ElapsedEventArgs e)
{
if (Global.AppExit)
{
Stop();
}
string[] files = Directory.GetFiles(_deleteFilePath, "*", SearchOption.AllDirectories);
try
{
foreach (string file in files)
{
FileInfo fileInfo = new FileInfo(file); //后期有必要再多年是否上传属性,上传了就删除
TimeSpan timeDifference = DateTime.Now - fileInfo.CreationTime;
if (timeDifference.TotalDays >= _intervalDays)
{
File.SetAttributes(file, FileAttributes.Normal);
File.Delete(file); //"对路径“”的访问被拒绝"
}
}
}
catch (Exception ex)
{
LogHelper.Instance.Error($"删除文件失败,_deleteFilePath:{_deleteFilePath},异常:{ex.Message}");
}
}
}
}

View File

@@ -0,0 +1,108 @@
using Cowain.Bake.Common;
using Cowain.Bake.Common.Core;
using System;
using System.IO;
using System.Threading.Tasks;
using Unity;
using Unity.Resolution;
namespace Cowain.Bake.Communication.FTP
{
public class FTPUpload
{
string _localFolderPath;
string _remoteFolderPath;
FtpHelper ftpClient;
public string Name { get; set; }
public IUnityContainer _unityContainer { get; set; }
public FTPUpload(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
ftpClient = _unityContainer.Resolve<FtpHelper>(new ParameterOverride("ipAddr","10.19.30.19"), new ParameterOverride("port", 21),
new ParameterOverride("userName", (object)"admin"), new ParameterOverride("password", (object)"123456"));
ftpClient.Connect();
}
public void Stop()
{
ftpClient.Close();
}
public void Start(string src, string desc)
{
_localFolderPath = src;
_remoteFolderPath = desc;
Task.WaitAny();
Task.Run(async () =>
{
while(true)
{
await Task.Delay(1000);
if (Global.AppExit)
{
ftpClient.Close();
return;
}
UploadToFTPService();
}
});
}
//string localFolderPath = @"E:\svn\CutingStack\CuttingStackingMachine\成都蜂巢6074\tex"; //本地要上传的文件位置 (界面可配)
//string remoteFolderPath = "/"; //MOM服务要上传到的位置 (界面可配)
void UploadToFTPService()
{
// 获取文件夹及其子文件夹中的所有文件
string[] files = Directory.GetFiles(_localFolderPath, "*", SearchOption.AllDirectories);
//string[] files = Directory.GetFiles(localFolderPath);
try
{
// 遍历每个文件
foreach (string file in files)
{
if (IsUpload(file))
{
if (ftpClient.UpLoad(file, _remoteFolderPath))
{
SetFileReadAccess(file, true); //上传的文件做标识(设为可读)
}
}
}
}
catch(Exception ex)
{
LogHelper.Instance.Error($"上传文件失败,localFolderPath:{_localFolderPath},remoteFolderPath:{_remoteFolderPath},异常:{ex.Message}");
}
}
//是否上传:可读为假就上传,为真不上传
bool IsUpload(string filePath)
{
return !IsFileReadable(filePath); //默认为假,不可读(可写)
}
//读为可读
public void SetFileReadAccess(string filePath, bool readOnly)
{
FileInfo fInfo = new FileInfo(filePath);
fInfo.IsReadOnly = readOnly;
}
public bool IsFileReadable(string filePath)
{
try
{
FileAttributes attributes = File.GetAttributes(filePath);
bool isReadable = (attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly;
return isReadable;
}
catch (Exception ex)
{
Console.WriteLine($"判断文件可读性时出现错误: {ex.Message}");
return false;
}
}
}
}

View File

@@ -0,0 +1,37 @@
using Cowain.Bake.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace Cowain.Bake.Communication
{
public class GenericFun
{
//public string GetVariableValue<T>(Expression<Func<T>> expr, List<TDeviceParam> devParms)
//{
// var memberExpr = (MemberExpression)expr.Body;
// foreach (var item in devParms)
// {
// if (memberExpr.Member.Name == item.Key)
// {
// return item.Value;
// }
// }
// return null;
//}
public T ConvertToType<T>(string value)
{
if (null == value)
{
return default(T);
}
// 使用Convert.ChangeType将字符串转换为泛型类型T
return (T)Convert.ChangeType(value, typeof(T));
}
}
}

View File

@@ -0,0 +1,50 @@
using Cowain.Bake.BLL;
using Cowain.Bake.Common;
using Cowain.Bake.Common.Models;
using Cowain.Bake.Model.Entity;
using Cowain.Bake.Model.Models;
using HslCommunication;
using Opc.Ua;
using Prism.Commands;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Cowain.Bake.Communication.Interface
{
public interface IPLCDevice//接口Plc
{
bool IsConnect { get; set; }//是否连接
int Id { get; set; }//id
string Name { get; set; }//名称
string DeviceName { get; set; }//设备名称
int ReadUseTime { get; set; }//读取使用时间
//字典
Dictionary<int, Variable> VariableDic { get; set; } //key:plc地址value:这个地址的相关信息,可以删除,基本不用
List<TagEntity> TagList { get; set; } //数据库中查询出来的
ObservableCollection<Variable> VariableList { get; set; } //一个PLC中的所有界面显示 与Storages的VariableList是同一块内存
List<StorageArea> Storages { get; set; } //Storages里也有一个VariableList一个PLC分成若干个VariableList组分组读取数据
void Heartbeat();
void Connect();//连接
void Close();//关闭
void StartRead();//开始读取
void AnalysisAddress();
void GetStorageArea();
void GetJsonParam(string param);
void ReadStorageArea();
List<DataValue> Reads(NodeId[] nodeIds);
OperateResult<T> Read<T>(string tag);
OperateResult<T> GetValue<T>(string paramName);
OperateResult<T> GetValue<T>(string paramName, int machineId, int number = 1);
Variable GetVariable(string paramName, int machineId, int number = 1);
//OperateResult Write<T>(string paramName, int machineId, int number, T data);
OperateResult Write<T>(string address, T data, int maxCount = Global.MAX_READS);
OperateResult Writes(string[] tags, object[] values, int maxCount = Global.MAX_READS);
}
}

View File

@@ -0,0 +1,23 @@
using Cowain.Bake.Common.Models;
using Cowain.Bake.Model;
using Cowain.Bake.Model.Entity;
using Cowain.Bake.Model.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Cowain.Bake.Communication.Interface
{
public interface IPLCService
{
List<TDeviceConfig> GetDeviceList();
List<TDeviceConfig> GetPLCList();
List<TDeviceConfig> GetScanList();
List<TagEntity> GetTagList(int plcId);
int DeleteTag(int tagId);
int SelectScript(Variable variable);
int DelectScript(Variable variable);
}
}

View File

@@ -0,0 +1,39 @@
using HslCommunication;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using Unity;
using Cowain.Bake.BLL;
namespace Cowain.Bake.Communication.Interface
{
public abstract class IScanCodeBase : BindableBase//, IScanCodeBase
{
public int Id { get; set; }
public string Name { get; set; }
public string DeviceName { get; set; }
public string Ip { get; set; }
public int Port { get; set; }
public string Command { get; set; }
public string CloseCommand { get; set; }
public string FilterRegex { get; set; }
public abstract bool IsConnect { get; set; }
public abstract bool Connect();
public abstract void Close();
public abstract void GetJsonParam(string param);
IUnityContainer _unityContainer;
IDialogService _dialogService;
public abstract OperateResult<string> ReadCode();
public IScanCodeBase(IUnityContainer unityContainer, IDialogService dialogService)
{
_unityContainer = unityContainer;
_dialogService = dialogService;
}
public void SetStatus(int Id, bool status)
{
_unityContainer.Resolve<DeviceConfigService>().UpdateStatus(Id, status);
}
}
}

View File

@@ -0,0 +1,27 @@
using Cowain.Injecting.Model;
using HslCommunication;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Cowain.Injecting.Communication.Interface
{
public interface IScanCodeDevice
{
int Id { get; set; }
string IpAddress { get; set; }
int Port { get; set; }
string Name { get; set; }
string Command { get; set; }
string FilterCodes { get; set; }
string DeviceName { get; set; }
bool IsConnect { get; set; }
bool Connect();
void Close();
OperateResult<string> ReadCode();
void GetJsonParam(string param);
}
}

View File

@@ -0,0 +1,133 @@
using System;
using System.IO;
using System.Net;
using System.Text;
using Cowain.Bake.Common.Core;
using System.Net.Http;
namespace Cowain.Bake.Communication.MOM
{
public class HttpClientHelper
{
public static string HttpPost1(string url, string param)
{
string result = "";
if (param.Length > 7000)
{
}
Encoding encoding = Encoding.UTF8;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/json";
request.Timeout = 30 * 1000;
byte[] buffer = encoding.GetBytes(param);
request.ContentLength = buffer.Length;
try
{
request.GetRequestStream().Write(buffer, 0, buffer.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
result = reader.ReadToEnd();
reader.Close();
}
}
}
catch(Exception ex)
{
LogHelper.Instance.GetCurrentClassWarn(ex.Message);
}
return result;
}
public static string HttpPost(string url, string param)
{
string result = "";
HttpResponseMessage response = null;
try
{
using (HttpClient client = new HttpClient())
{
var data = new StringContent(param, Encoding.UTF8, "application/json");
// 设置超时时间为30秒
client.Timeout = TimeSpan.FromSeconds(20);
response = client.PostAsync(url, data).Result;
if (response.IsSuccessStatusCode)
{
result = response.Content.ReadAsStringAsync().Result;
}
else
{
LogHelper.Instance.GetCurrentClassError($"HTTP POST request failed:{response.StatusCode},\n{url},\n{param}");
}
}
}
catch (Exception ex)
{
if (null == response)
{
LogHelper.Instance.GetCurrentClassError($"HTTP POST failed, 超时:{ex.Message},\n{url},\n{param}");
}
else
{
LogHelper.Instance.GetCurrentClassError($"HTTP POST failed,StatusCode:{response.StatusCode},{ex.Message},\n{url},\n{param}");
}
}
return result;
}
}
}
/*
public static async Task<string> HttpPost(string url, string param)
{
string result = "";
if (param.Length < 7000)
{
}
else
{
}
Encoding encoding = Encoding.UTF8;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/json";
request.Timeout = 5 * 1000;
byte[] buffer = encoding.GetBytes(param);
request.ContentLength = buffer.Length;
var httpTask1 = Task.Run(() =>
request.GetRequestStream().Write(buffer, 0, buffer.Length));
var timeouttask = Task.Delay(5000);
var completedTask = await Task.WhenAny(httpTask1, timeouttask);
if (completedTask == timeouttask)
{
LogHelper.Instance.Warn("请求MOM超时");
return result;
}
//request.GetRequestStream().Write(buffer, 0, buffer.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
result = reader.ReadToEnd();
reader.Close();
}
}
return result;*/

View File

@@ -0,0 +1,479 @@
using System;
using System.Collections.Generic;
using JSON = Newtonsoft.Json.JsonConvert;
using Newtonsoft.Json;
using Unity;
using System.Collections.Concurrent;
using Cowain.Bake.BLL;
using Cowain.Bake.Common.Enums;
using Cowain.Bake.Model;
using static Cowain.Bake.Common.Models.MESModel;
using Cowain.Bake.Model.Models;
using Cowain.Bake.Common.Core;
using System.Linq;
namespace Cowain.Bake.Communication.MOM
{
public class MESProcess
{
readonly ConcurrentDictionary<int, float> dicMaxTemp = null; //表示该变量的引用(指针)不可变
string url = null;
public string URL
{
get
{
if (url != null)
{
return url;
}
TDeviceConfig dev = _unityContainer.Resolve<DeviceConfigService>().GetConfig(EDeviceType.MOM)[0];
GetJsonParam(dev.Json);
return url;
}
}
readonly IUnityContainer _unityContainer;
public MESProcess(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
dicMaxTemp = new ConcurrentDictionary<int, float>();
}
public void GetJsonParam(string param)
{
dynamic d = JsonConvert.DeserializeObject<dynamic>(param);
this.url = d.URL;
}
/// <summary>
/// 心跳
/// </summary>
/// <returns></returns>
public MESReturnCmdModel Alive()
{
EqptAlive eqptAlive = new EqptAlive();
DateTime currentTime = DateTime.Now;
DateTime oneMinuteAgo = currentTime.AddMinutes(-1);
eqptAlive.Info.EquipmentCode = _unityContainer.Resolve<SysSetupService>().GetValueByParaID(ESysSetup.DeviceNum.ToString()); ;
eqptAlive.Info.PPM = _unityContainer.Resolve<BatteryInfoService>().GetPPM(oneMinuteAgo, currentTime).ToString();
var resultModel = SendData(JSON.SerializeObject(eqptAlive), (int)EMesLogClass.EqptAlive, true);
//string result = HttpClientHelper.HttpPost(URL, JSON.SerializeObject(eqptAlive));
//var resultModel = JSON.DeserializeObject<MESReturnCmdModel>(result);
return resultModel;
}
//2.设备状态 报警要把报警信息传过去与PLC确认
public MESReturnCmdModel MESEqptStatus(UInt16 status, List<TAlarm> models)
{
string urlCmd = URL;
EqptStatus eqptStatu = new EqptStatus();
eqptStatu.Info.EquipmentCode = _unityContainer.Resolve<SysSetupService>().GetValueByParaID(ESysSetup.DeviceNum.ToString());// "EC001";
eqptStatu.Info.StatusCode = status.ToString();
if (null != models)
{
foreach(var item in models)
{
eqptStatu.Info.AlertInfo.Add(
new AlerInfoModel()
{
AlertMessage = item.Desc,
AlertCode = item.Id.ToString()
});
}
}
return SendData(JSON.SerializeObject(eqptStatu), (int)EMesLogClass.Status);
}
/// <summary>
/// 3.设备报警
/// </summary>
/// <param name="arrayAlert"></param>
public void MESEqptAlert(List<AlertInfoModel> arrayAlert)
{
if (0 == arrayAlert.Count) return;
EqptAlertModel eqptAlertModel = new EqptAlertModel();
EqptAlert eqptAlert = new EqptAlert();
eqptAlertModel.AlertInfo = arrayAlert;
eqptAlert.Info = eqptAlertModel;
eqptAlert.Info.EquipmentCode = _unityContainer.Resolve<SysSetupService>().GetValueByParaID(ESysSetup.DeviceNum.ToString());
SendData(JSON.SerializeObject(eqptAlert), (int)EMesLogClass.Alarm, false);
}
//4.工艺参数请求:心跳为2时请求
public EqptParameterReturnCmd GetProcessParam()
{
EqptParameter process = new EqptParameter();
process.Info.EquipmentCode = _unityContainer.Resolve<SysSetupService>().GetValueByParaID(ESysSetup.DeviceNum.ToString());
var result = SendData<EqptParameterReturnCmd>(JSON.SerializeObject(process), (int)EMesLogClass.ParameterRequest);
if (result == default(EqptParameterReturnCmd))
{
LogHelper.Instance.Error($"获取工艺参数失败!请求内容:{JSON.SerializeObject(process)}");
return null;
}
return result;
}
/// <summary>
///5 参数变更
/// </summary>
/// <param name="userId"></param>
/// <param name="paramInfo"></param>
/// <returns></returns>
public MESReturnCmdModel ChangeParam(string userId, List<EqptParameterModel> paramInfo)
{
ParameterChangeCmd param = new ParameterChangeCmd();
//param.Info = new ParameterChange();
param.Info.EquipmentCode = _unityContainer.Resolve<SysSetupService>().GetValueByParaID(ESysSetup.DeviceNum.ToString());
param.Info.EmployeeNo = userId;
param.Info.ParameterInfo = paramInfo;
return SendData(JSON.SerializeObject(param), (int)EMesLogClass.ParameterChange);
}
//6.联机请求
public MESReturnCmdModel EqptRun(string user, string pwd, string equipmentModel)
{
EqptRunCmd eqptRunCmd = new EqptRunCmd();
EqptRun eqptRun = new EqptRun();
eqptRun.EmployeeNo = user;
eqptRun.Password = pwd;
eqptRun.EquipmentModel = equipmentModel;
eqptRun.EquipmentCode = _unityContainer.Resolve<SysSetupService>().GetValueByParaID(ESysSetup.DeviceNum.ToString());
eqptRunCmd.Info = eqptRun;
return SendData(JSON.SerializeObject(eqptRunCmd), (int)EMesLogClass.EqptRun);
}
/// <summary>
///7 电芯状态获取(进站电芯)
/// </summary>
/// <returns></returns>
public MESReturnCmdModel GetBatteryStatus(string batteryCode)
{
CellStateCmd cellStateCmd = new CellStateCmd();
//cellStateCmd.Info = new CellState();
cellStateCmd.Info.CellNo = batteryCode;
cellStateCmd.Info.EquipmentCode = _unityContainer.Resolve<SysSetupService>().GetValueByParaID(ESysSetup.DeviceNum.ToString());
return SendData(JSON.SerializeObject(cellStateCmd), (int)EMesLogClass.GetCellState);
}
/// <summary>
///8 烘烤进站
/// </summary>
/// <param name="LocationID"></param>
/// <param name="palletCode"></param>
/// <param name="batteryCodes"></param>
public void MESBakingInput(string LocationID, string palletCode, List<string> batteryCodes, string recipeName)
{
BakingInputCmd bakingInputCmd = new BakingInputCmd();
//bakingInputCmd.Info = new BakingInput();
bakingInputCmd.Info.EquipmentCode = _unityContainer.Resolve<SysSetupService>().GetValueByParaID(ESysSetup.DeviceNum.ToString());// "EC001";
bakingInputCmd.Info.TrayNo = palletCode;
bakingInputCmd.Info.LocationID = LocationID;
bakingInputCmd.Info.RecipeName = recipeName;
List<CellModel> cellModels = new List<CellModel>();
batteryCodes.ForEach((x) =>
{
cellModels.Add(new CellModel() { CellNo = x });
});
bakingInputCmd.Info.Cells = cellModels;
SendData(JSON.SerializeObject(bakingInputCmd), (int)EMesLogClass.EnterStation, true);
}
/// <summary>
/// 9.烘烤过程参数采集
/// </summary>
/// <returns></returns>
public void MESBakingParameter(float vacuum, float[] temps, string LocationID)
{
int index = 0;
BakingParameterCmd param = new BakingParameterCmd();
//param.Info = new BakingParameter();
List<ProcessData> processDatas = new List<ProcessData>();
param.Info.LocationID = LocationID;
param.Info.LocalTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); ;
param.Info.EquipmentCode = _unityContainer.Resolve<SysSetupService>().GetValueByParaID(ESysSetup.DeviceNum.ToString());
//真空
ProcessData parameterInfo = new ProcessData();
parameterInfo.ParameterCode = "HK-0017";
parameterInfo.ParameterType = "float";
parameterInfo.Value = vacuum.ToString();
processDatas.Add(parameterInfo);
//温度
int i = 0;
foreach (var temp in temps)
{
if (i % 2 != 0)
{
index++;
parameterInfo = new ProcessData();
parameterInfo.ParameterCode = "HK-00" + $"{12 + index}";
parameterInfo.ParameterType = "float";
parameterInfo.Value = temp.ToString();
parameterInfo.Description = $"巡检-温度{index}";
processDatas.Add(parameterInfo);
}
i++;
}
param.Info.ParameterInfo = processDatas;
SendData(JSON.SerializeObject(param), (int)EMesLogClass.BakingParameter, false);
}
/// <summary>
///10. 烘烤出站
/// </summary>
public MESReturnCmdModel MESBakingOutput(string LocationID, TPalletInfo palletInfo, List<TBatteryInfo> batterys, bool outFlag, bool realTimeSend)
{
BakingOutputCmd outputParams = new BakingOutputCmd();
outputParams.Info.EquipmentCode = _unityContainer.Resolve<SysSetupService>().GetValueByParaID(ESysSetup.DeviceNum.ToString());
outputParams.Info.TrayNo = palletInfo.PalletCode;
outputParams.Info.LocationID = LocationID;
outputParams.Info.OutFlag = outFlag ? "Y" : "N";
List<CellModel> cellModels = new List<CellModel>();
WaterModel waterModel = new WaterModel();
if (!string.IsNullOrEmpty(palletInfo.WaterValue))
{
var waterModelList = JsonConvert.DeserializeObject<List<WaterModel>>(palletInfo.WaterValue); //输入水含量异常,导致
waterModel = waterModelList.OrderByDescending(x => x.Id).First(); //最ID最大的
}
var batteryCodes = batterys.Select(x => x.BatteryCode).ToList();
batteryCodes.ForEach((x) =>
{
cellModels.Add(new CellModel() { CellNo = x });
});
outputParams.Info.Cells = cellModels;
string RowAndColumn = "";
foreach (var item in batterys)
{
RowAndColumn += $"{item.PositionX}行,{item.PositionY}列,";
}
List<ParametersModel> bakingOutputDatas = new List<ParametersModel>();
ParametersModel bakingOutputData = new ParametersModel();
bakingOutputData = new ParametersModel();
bakingOutputData.ParameterCode = "HK-0001";
bakingOutputData.ParameterDesc = "烘烤号";
var cavity = _unityContainer.Resolve<MemoryDataProvider>().CavityInfo.Where(x => x.Id == (palletInfo.BakingPosition ?? 0)).FirstOrDefault();
bakingOutputData.Value = (cavity == null) ? "" : cavity.Name;
bakingOutputDatas.Add(bakingOutputData);
bakingOutputData = new ParametersModel();
bakingOutputData.ParameterCode = "HK-0002";
bakingOutputData.ParameterDesc = "托盘号";
bakingOutputData.Value = palletInfo.PalletCode;
bakingOutputDatas.Add(bakingOutputData);
bakingOutputData = new ParametersModel();
bakingOutputData.ParameterCode = "HK-0003";
bakingOutputData.ParameterDesc = "行列";
bakingOutputData.Value = $"{RowAndColumn}";
bakingOutputDatas.Add(bakingOutputData);
bakingOutputData = new ParametersModel();
bakingOutputData.ParameterCode = "HK-0004";
bakingOutputData.ParameterDesc = "进站时间";
bakingOutputData.Value = null == palletInfo.LoadingBegingTime ? DateTime.Now.ToString() : palletInfo.LoadingBegingTime.Value.ToString();
bakingOutputDatas.Add(bakingOutputData);
bakingOutputData = new ParametersModel();
bakingOutputData.ParameterCode = "HK-0005";
bakingOutputData.ParameterDesc = "出站时间";
bakingOutputData.Value = DateTime.Now.ToString();
bakingOutputDatas.Add(bakingOutputData);
bakingOutputData = new ParametersModel();
bakingOutputData.ParameterCode = "HK-0006";
bakingOutputData.ParameterDesc = "烘烤开始时间";
bakingOutputData.Value = null == palletInfo.BakingBeginTime ? DateTime.Now.ToString() : palletInfo.BakingBeginTime.Value.ToString();
bakingOutputDatas.Add(bakingOutputData);
bakingOutputData = new ParametersModel();
bakingOutputData.ParameterCode = "HK-0007";
bakingOutputData.ParameterDesc = "烘烤结束时间";
bakingOutputData.Value = null == palletInfo.BakingOverTime ? DateTime.Now.ToString() : palletInfo.BakingOverTime.Value.ToString();
bakingOutputDatas.Add(bakingOutputData);
bakingOutputData = new ParametersModel();
bakingOutputData.ParameterCode = "HK-0008";
bakingOutputData.ParameterDesc = "电芯冷却温度";
var temps = batterys.Select(x => x.CoolTemp).ToList();
bakingOutputData.Value = string.Join(", ", temps);
bakingOutputDatas.Add(bakingOutputData);
bakingOutputData = new ParametersModel();
bakingOutputData.ParameterCode = "HK-0011";
bakingOutputData.ParameterDesc = "冷却开始时间";
bakingOutputData.Value = DateTime.Now.ToString();
bakingOutputDatas.Add(bakingOutputData);
bakingOutputData = new ParametersModel();
bakingOutputData.ParameterCode = "HK-0012";
bakingOutputData.ParameterDesc = "冷却结束时间";
bakingOutputData.Value = DateTime.Now.ToString();
bakingOutputDatas.Add(bakingOutputData);
bakingOutputData = new ParametersModel();
bakingOutputData.ParameterCode = "HK-0013";
bakingOutputData.ParameterDesc = "正极水含量";
bakingOutputData.Value = waterModel.AnodeWaterValue;
bakingOutputDatas.Add(bakingOutputData);
bakingOutputData = new ParametersModel();
bakingOutputData.ParameterCode = "HK-0014";
bakingOutputData.ParameterDesc = "隔膜水含量";
bakingOutputData.Value = waterModel.SeptumWaterValue;
bakingOutputDatas.Add(bakingOutputData);
bakingOutputData = new ParametersModel();
bakingOutputData.ParameterCode = "HK-0015";
bakingOutputData.ParameterDesc = "负极水含量";
bakingOutputData.Value = waterModel.CathodeWaterValue;
bakingOutputDatas.Add(bakingOutputData);
//bakingOutputData = new ParametersModel();
//bakingOutputData.ParameterCode = "HK-0019";
//bakingOutputData.ParameterDesc = "是否出站";
//bakingOutputData.Value = outFlag ? "Y" : "N";
//bakingOutputDatas.Add(bakingOutputData);
bakingOutputData = new ParametersModel();
bakingOutputData.ParameterCode = "HK-0020";
bakingOutputData.ParameterDesc = "最高温度";
bakingOutputData.Value = GetMaxTemperature(palletInfo.VirtualId).ToString();
bakingOutputDatas.Add(bakingOutputData);
outputParams.Info.Parameters = bakingOutputDatas;
//return outputParams;
return SendData(JSON.SerializeObject(outputParams), (int)EMesLogClass.ExitStation, realTimeSend);
}
public float GetMaxTemperature(int virtualId)
{
float value = 0;
if (!dicMaxTemp.TryGetValue(virtualId, out value)) //可以不删除dicMaxTemp因为量不大
{
LogHelper.Instance.Warn("开始获取最高温度");
value = _unityContainer.Resolve<StoveSctualPatrolService>().GetStoveMaxTemp(virtualId);
LogHelper.Instance.Warn("结束获取最高温度");
dicMaxTemp.TryAdd(virtualId, value);
}
return value;
}
public MESReturnCmdModel SendData(string info, sbyte msgType = (int)EMesLogClass.ExitStation, bool isEanble = true)
{
var result = GetRecvData(info, msgType, isEanble);
if (string.IsNullOrEmpty(result))
{
return null;
}
return JSON.DeserializeObject<MESReturnCmdModel>(result);
}
public T SendData<T>(string info, sbyte msgType, bool isEanble = true)
{
var result = GetRecvData(info, msgType, isEanble);
if (string.IsNullOrEmpty(result))
{
return default(T); //default(T)
}
return JSON.DeserializeObject<T>(result);
}
public string GetRecvData(string info, sbyte msgType, bool isEanble = true)
{
CCommandType ct = new CCommandType();
ct.UrlCmd = URL;
TMesData mesModel = new TMesData();
mesModel.CreateTime = DateTime.Now;
mesModel.CommandType = JSON.SerializeObject(ct);
mesModel.Content = info; //JSON.SerializeObject(obj);
mesModel.MsgType = msgType;
if (int.Parse(_unityContainer.Resolve<SysSetupService>().GetValueByParaID(ESysSetup.MOMEnable.ToString())) == (int)EMOMEnable.Enable
&& isEanble) //又发又存
{
mesModel.SendTime = DateTime.Now;
string result = HttpClientHelper.HttpPost(URL, info);
mesModel.RecvTime = DateTime.Now;
mesModel.RecvContent = result;
mesModel.SendFlag = string.IsNullOrEmpty(result) ? (sbyte)EMesUpLoadStatus.Fail : (sbyte)EMesUpLoadStatus.Success;
if(msgType != (int)EMesLogClass.EqptAlive)
{
_unityContainer.Resolve<MesDataService>().Insert(mesModel); //保存数据
}
if (string.IsNullOrEmpty(result))
{
return null;
}
WriteRequestLog(info);
WriteResponseLog(result);
//var resultModel = JSON.DeserializeObject<MESReturnCmdModel>(result);
return result;
}
else if (int.Parse(_unityContainer.Resolve<SysSetupService>().GetValueByParaID(ESysSetup.MOMEnable.ToString())) == (int)EMOMEnable.Disable
|| !isEanble) //只存不发
{
mesModel.SendFlag = (sbyte)EMesUpLoadStatus.Wait;
_unityContainer.Resolve<MesDataService>().Insert(mesModel); //保存数据
return null;
}
else //不发,也不存
{
return null;
}
}
///发送
public void WriteRequestLog(string info)
{
dynamic d = JsonConvert.DeserializeObject<dynamic>(info);
string cmd = d.Cmd;
string dateTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
string uuid = d.Info.Key;
LogHelper.Instance.Trace($"[Request][{cmd}][{dateTime}][{uuid}][{info}]");
}
/// <summary>
/// 接收
/// </summary>
/// <param name="info"></param>
public void WriteResponseLog(string info)
{
dynamic d = JsonConvert.DeserializeObject<dynamic>(info);
string cmd = d.Cmd;
string dateTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
string uuid = d.Info.Key;
LogHelper.Instance.Trace($"[Response][{cmd}][{dateTime}][{uuid}][{info}]");
}
public string GetEquipmentCode(int MachineID)
{
string equipmentCode = _unityContainer.Resolve<SysSetupService>().GetValueByParaID(ESysSetup.DeviceNum.ToString());
string LineCode = equipmentCode.Substring(equipmentCode.Length - 2);
MachineID = int.Parse(LineCode) + MachineID - 1;
string formattedNumber = MachineID.ToString().PadLeft(2, '0');
equipmentCode = equipmentCode.Replace(LineCode, formattedNumber);
return equipmentCode;
}
}
}

View File

@@ -0,0 +1,20 @@
using HslCommunication;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Cowain.Bake.Communication.Models
{
public class ExOperateResult<T> : OperateResult<T>
{
public DateTime UpdateTime { set; get; } = DateTime.Now; //更新时间
}
public class ExOperateResult : OperateResult
{
public DateTime UpdateTime { set; get; } = DateTime.Now; //更新时间
}
}

View File

@@ -0,0 +1,830 @@
using Cowain.Bake.Common.Core;
using Cowain.Bake.Communication.Interface;
using Cowain.Bake.Model.Entity;
using HslCommunication;
using HslCommunication.Core;
using Newtonsoft.Json;
using OpcUaHelper;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Unity;
using Cowain.Bake.Common.Models;
using Cowain.Bake.Model.Models;
using Cowain.Bake.Common;
using Opc.Ua;
using Cowain.Bake.BLL;
using Cowain.Bake.Common.Enums;
namespace Cowain.Bake.Communication.PLC
{
public abstract class PLCBase : BindableBase, IPLCDevice
{
protected IUnityContainer _unityContainer;
protected IDialogService _dialogService;
public virtual IReadWriteNet PLC { get; set; }
public OpcUaClient OPC { get; set; }
public IByteTransform ByteTransform { get; set; }
public virtual string IpAddress { get; set; } = "127.0.0.1";
public virtual int Port { get; set; }
public virtual byte Slot { get; set; }
public virtual string ConnectString { get; set; }
CancellationTokenSource cts = new CancellationTokenSource();
protected PLCBase(IUnityContainer unityContainer, IDialogService dialogService)
{
_unityContainer = unityContainer;
_dialogService = dialogService;
}
private int readUseTime;
public int ReadUseTime
{
get { return readUseTime; }
set { SetProperty(ref readUseTime, value); }
}
private bool isConnect;
public bool IsConnect
{
get { return isConnect; }
set { SetProperty(ref isConnect, value); }
}
public int Id { get; set; }
public string Name { get; set; }
public string DeviceName { get; set; }
public Dictionary<int, Variable> VariableDic { get; set; } = new Dictionary<int, Variable>();
public ObservableCollection<Variable> VariableList { get; set; } = new ObservableCollection<Variable>(); //数组遍历器
public List<TagEntity> TagList { get; set; } = new List<TagEntity>();
public List<StorageArea> Storages { get; set; } = new List<StorageArea>(); //1个PLC一个首地址及所对应的标签信息
public abstract void Close();
public abstract void Connect();
public abstract void GetJsonParam(string param);
bool? lastConnect = null;
public virtual void StartRead()
{
Task.Run(async () =>
{
await Task.Delay(2000); //等待OPC初始化完成
Stopwatch sw = new Stopwatch();
while (true)
{
if (Global.AppExit)
{
return;
}
try
{
if (!IsConnect)
{
if (VariableList != null && VariableList.Count > 0)
{
foreach (var tag in VariableList)
{
tag.Quality = false;
}
}
Connect();
}
else
{
if (IsConnect)
{
sw.Restart();
ReadStorageArea();
sw.Stop();
ReadUseTime = (int)sw.ElapsedMilliseconds;
sw.Reset();
if (ReadUseTime > 3000)
{
LogHelper.Instance.Warn($"{ConnectString}:刷新所有数据时间:" + ReadUseTime + "ms");
}
}
}
}
catch(Exception ex)
{
LogHelper.Instance.Error($"全局读取数据失败:{ex.Message}");
}
if (lastConnect != IsConnect)
{
lastConnect = IsConnect;
//_unityContainer.Resolve<BasicInfoViewModel>().PLCStatus = IsConnect;
//_unityContainer.Resolve<DeviceConfigService>().UpdateStatus(this.Name, IsConnect);
_unityContainer.Resolve<DeviceConfigService>().UpdateStatus(this.Id, IsConnect);
}
// 触发 GC
GC.Collect();
GC.WaitForPendingFinalizers();
await Task.Delay(1000);
}
});
}
public virtual void Heartbeat()
{
Task.Run(async () =>
{
while (!cts.Token.IsCancellationRequested)
{
if (Global.AppExit)
{
return;
}
await Task.Delay(Global.HEARTBEAT_INTERVAL_TIME);
if (null == PLC || !IsConnect)
{
continue;
}
var node = (from secondaryList in Storages
from item in secondaryList.VariableList
where item.VarDesc == "心跳"
select item).FirstOrDefault();
if (null == node)
{
LogHelper.Instance.Warn("查询心跳节点失败");
continue;
}
OperateResult result = Write<Int16>(node.Address + node.VarName, 1); //只写一个心跳就行了
if (!result.IsSuccess)
{
//LogHelper.Instance.Warn($"DeviceId:{Storages[0].DeviceId}:写心跳节点失败");
}
}
}, cts.Token);
}
public virtual int GetReadMaxLength(Variable variable)
{
return 101;
}
public virtual void AddressSplit(TagEntity tag)
{
//按modbus tcp解析 格式:x=3;0
string[] ss = tag.Address.Split(';');
if (ss.Length == 2)
{
VariableDic[(int)tag.Id].AddressType = ss[0];
VariableDic[(int)tag.Id].Address = ss[1];
}
}
/// <summary>
/// 赋值类型长度
/// </summary>
/// <param name="tag"></param>
public virtual void SetReadLength(TagEntity tag)
{
string varType = tag.VarType;
Match m = Regex.Match(tag.VarType, @"(?<=\[)([0-9]+)(?=\])", RegexOptions.Singleline);
if (m.Success)
{
//说明是数组[]
//VariableDic[tag.VarName].ReadLength = Convert.ToInt32(m.Value); 这是个BUG
VariableDic[(int)tag.Id].ArrayLength = Convert.ToInt32(m.Value);
Match mType = Regex.Match(tag.VarType, @"(.*)(?=\[)", RegexOptions.Singleline);
varType = mType.Value;
}
switch (varType)
{
case "BOOL":
case "BYTE":
case "INT16":
case "UINT16":
VariableDic[(int)tag.Id].ReadLength = 1;
break;
case "INT32":
case "UINT32":
case "FLOAT":
VariableDic[(int)tag.Id].ReadLength = 2;
break;
default:
LogHelper.Instance.Error("不支持的数据类型:" + tag.VarType);
break;
}
}
public virtual void AnalysisAddress()
{
foreach (var tag in TagList)
{
AddressSplit(tag);
SetReadLength(tag);
}
}
public virtual void GetStorageArea()
{
Storages.Clear();
var query = (from v in VariableList //query = List<IGrouping<string, Variable>> //按地址类型分组如x=3一组
orderby Convert.ToInt16(v.Address), v.ReadLength
group v by v.AddressType into a
where a.Count() > 0
orderby a.Key
select a).ToList(); //modbus地址类型分组
/* modbus地址分类
0x01 读取线圈的操作,
0x02 读取离散的操作,
0x03 读取寄存器的值,
0x04 读取输入寄存器的值
0x05 写一个线圈操作,
0x06 写一个寄存器值,
0x0F 批量写线圈操作,
0x10 批量写寄存器值,
0x16 掩码写入的寄存器大部分的modbus设备不支持
*/
int k = query.Count;
foreach (var g in query)
{
int k1 = g.Count();
var first = g.First();//first:Variable,g:Dictionary<string,List<Variable>>
var totalLengthQuery1 = (from a in g //分块读数据
group a by (Convert.ToInt16(a.Address) - Convert.ToInt16(first.Address) + a.ReadLength) / GetReadMaxLength(a)).ToList();
var totalLengthQuery = (from a in g //分块读数据,100个数据分一组在地址类型上再按100为一组分第二次组
group a by (Convert.ToInt16(a.Address) - Convert.ToInt16(first.Address) + a.ReadLength) / GetReadMaxLength(a) into b
select new
{
VarList = b, //Regex.Replace(a.VarType, @"\[.*\]", string.Empty)
Id = b.Key, //(Convert.ToInt16(a.Address) - Convert.ToInt16(first.Address) + a.ReadLength) / GetReadMaxLength(a)
AddressType = b.First().AddressType, //AddressType类型是Variable
StartAddress = b.First().Address,
GroupReadLength = (Convert.ToInt16(b.Last().Address) - Convert.ToInt16(b.First().Address) + b.Last().ReadLength)
}).ToList();
totalLengthQuery.ForEach(x =>
{
List<Variable> variables = x.VarList.ToList();
foreach (var variable in variables)
{
//计算offset,字节偏移
variable.Offset = (Convert.ToInt16(variable.Address) - Convert.ToInt16(x.StartAddress)) * 2;
}
Storages.Add(new StorageArea()
{
//Id = x.Id,
AddressType = x.AddressType,
StartAddress = x.StartAddress,
Len = x.GroupReadLength,
VariableList = variables
});
});
}
GetReadAddress();
}
public virtual void GetReadAddress()
{
foreach (var storage in Storages)
{
storage.ReadAddress = storage.AddressType + storage.StartAddress;
}
}
public virtual OperateResult<T> Read<T>(string tag)
{
return null;
}
public virtual OperateResult<T> GetValue<T>(string paramName)
{
return null;
}
public virtual OperateResult<T> GetValue<T>(string paramName, int machineId, int number = 0)
{
return null;
}
public virtual Variable GetVariable(string paramName, int machineId, int number = 0)
{
return null;
}
public virtual OperateResult Write<T>(string paramName, int machineId, int number, T data)
{
return null;
}
public virtual void ReadStorageArea()
{
try
{
foreach (var item in Storages)
{
bool readError = false;
for (int i = 0; i < Global.MAX_READS; i++)
{
var read = PLC.Read(item.ReadAddress, (ushort)item.Len);
if (read.IsSuccess)
{
IsConnect = true;
readError = false;
//读成功
if (item.VariableList != null)
{
foreach (var variable in item.VariableList)
{
AnalyseData(read.Content, variable);
}
}
break;
}
else
{
foreach (var val in item.VariableList)
{
val.Quality = false;
}
LogHelper.Instance.Error($"读错误,,ErrorCode:{read.ErrorCode},失败:" + read.Message);
}
readError = true;
Thread.Sleep(30);
}
Thread.Sleep(30);
if (readError)
{
IsConnect = false;
}
}
}
catch(Exception ex)
{
IsConnect = false;
LogHelper.Instance.Error(ex.Message);
}
}
public virtual void AnalyseData(byte[] data, Variable variable)
{
if (data != null && data.Length > 0)
{
if (variable.ArrayLength > 1)
{
//说明是数组[]
//variable.ArrayLength = Convert.ToInt32(m.Value);
switch (variable.VarType)
{
case "BOOL":
variable.CurValue = ByteTransform.TransBool(data, variable.Offset);
variable.Quality = true;
break;
case "BYTE":
variable.CurValue = ByteTransform.TransByte(data, variable.Offset, variable.ArrayLength);
variable.Quality = true;
break;
case "INT16":
variable.CurValue = Array.ConvertAll(ByteTransform.TransInt16(data, variable.Offset, variable.ArrayLength), ele => ele.ToString());
variable.Quality = true;
break;
case "UINT16":
variable.CurValue = Array.ConvertAll(ByteTransform.TransUInt16(data, variable.Offset, variable.ArrayLength), ele => ele.ToString());
variable.Quality = true;
break;
case "INT32":
variable.CurValue = Array.ConvertAll(ByteTransform.TransInt32(data, variable.Offset, variable.ArrayLength), ele => ele.ToString());
variable.Quality = true;
break;
case "UINT32":
variable.Value = Array.ConvertAll(ByteTransform.TransUInt32(data, variable.Offset, variable.ArrayLength), ele => ele.ToString());
variable.Quality = true;
break;
case "FLOAT":
variable.Value = Array.ConvertAll(ByteTransform.TransSingle(data, variable.Offset, variable.ArrayLength), ele => ele.ToString());
variable.Quality = true;
break;
//case "STR":
// variable.CurValue = ByteTransform.TransString(data, variable.Offset, variable.ArrayLength, Encoding.Default);
// variable.Quality = true;
// break;
default:
LogHelper.Instance.Error("不支持的数据类型:" + variable.VarType);
break;
}
}
else
{
//值类型tostring不会装箱
switch (variable.VarType)
{
case "BOOL":
variable.CurValue = ByteTransform.TransBool(data, 1).ToString();
variable.Quality = true;
break;
case "BYTE":
variable.CurValue = ByteTransform.TransByte(data, variable.Offset).ToString();
variable.Quality = true;
break;
case "INT16":
variable.CurValue = ByteTransform.TransInt16(data, variable.Offset).ToString();
variable.Quality = true;
break;
case "UINT16":
data[0] = 33;
data[1] = 251;
variable.CurValue = ByteTransform.TransUInt16(data, variable.Offset).ToString();
variable.Quality = true;
break;
case "INT32":
variable.CurValue = ByteTransform.TransInt32(data, variable.Offset).ToString();
variable.Quality = true;
break;
case "UINT32":
variable.CurValue = ByteTransform.TransUInt32(data, variable.Offset).ToString();
variable.Quality = true;
break;
case "FLOAT":
float f = ByteTransform.TransSingle(data, variable.Offset);
variable.CurValue = ByteTransform.TransSingle(data, variable.Offset).ToString();
variable.Quality = true;
break;
default:
LogHelper.Instance.Error("不支持的数据类型:" + variable.VarType);
break;
}
//variable.Value = new string[] { variable.CurValue };
}
if (variable.TrigEnable)
{
dynamic d = JsonConvert.DeserializeObject<dynamic>(variable.TrigJson);
string fName = d.Func;
string vals = d.Value;
string key = d.Key;
string desc = d.Desc;
string serviceName = d.Service;
if (string.IsNullOrEmpty(serviceName))
{
serviceName = "TrigerService";
}
if (!string.IsNullOrEmpty(variable.OldValue.ToString()))
{
if (string.Equals(variable.OldValue, variable.CurValue))
{
if (vals == variable.CurValue.ToString())
{
//异步执行
//this.TrigServiceAsync(serviceName, fName, VariableDic[tag.VarName].FuncJson);
//int scriptId = variable.ScriptId;
//if (scriptId > 0)
//{
// var sm = _unityContainer.Resolve<IScriptManage>();
// var script = sm.ScriptList.Where(x => x.Id == scriptId).FirstOrDefault();
// if (script != null)
// {
// string funcJson = variable.Json;
// if (!string.IsNullOrEmpty(funcJson))
// {
// TrigScriptAsync(script, variable.Json);
// }
// }
// else
// {
// LogHelper.Instance.Error($"脚本执行异常:没找到脚本-{scriptId}");
// }
//}
}
}
}
}
variable.OldValue = variable.CurValue;
}
}
//private void CopyBytes(byte[] data, Variable variable, int len)
//{
// variable.CurValue = new byte[len];
// Buffer.BlockCopy(data, variable.Offset, variable.CurValue, 0, len);
//}
public virtual OperateResult Writes(string[] tags, object[] values, int maxCount = Global.MAX_READS)
{
return null;
}
public virtual List<DataValue> Reads(NodeId[] nodeIds)
{
return null;
}
public abstract OperateResult Write<T>(string address, T data, int maxCount = 5);
public virtual OperateResult Write<T>(dynamic plc, string address, T data, int maxCount = 5)
{
var res = Write<T>(plc, address, data);
for (int i = 0; i < maxCount; i++)
{
if (res.IsSuccess)
{
break;
}
Thread.Sleep(15);
res = Write<T>(plc, address, data);
}
return res;
}
public virtual OperateResult Write<T>(dynamic plc, string address, T data)
{
if (!IsConnect)
{
return new OperateResult("未连接PLC");
}
Type type = typeof(T);
OperateResult resultdata = null;
try
{
if (type == typeof(short))
{
if (data is short one)
{
resultdata = plc.Write(address, one);
}
}
else if (type == typeof(ushort))
{
if (data is ushort one)
{
resultdata = plc.Write(address, one);
}
}
else if (type == typeof(int))
{
if (data is int one)
{
resultdata = plc.Write(address, one);
}
}
else if (type == typeof(uint))
{
if (data is uint one)
{
resultdata = plc.Write(address, one);
}
}
else if (type == typeof(long))
{
if (data is long one)
{
resultdata = plc.Write(address, one);
}
}
else if (type == typeof(ulong))
{
if (data is ulong one)
{
resultdata = plc.Write(address, one);
}
}
else if (type == typeof(float))
{
if (data is float one)
{
resultdata = plc.Write(address, one);
}
}
else if (type == typeof(double))
{
if (data is double one)
{
resultdata = plc.Write(address, one);
}
}
else if (type == typeof(bool))
{
if (data is bool state)
{
resultdata = plc.Write(address, state);
}
}
else if (type == typeof(short[]) || type == typeof(List<short>))
{
if (data is short[] arr)
{
resultdata = plc.Write(address, arr);
}
else if (data is List<short> list)
{
//list
resultdata = plc.Write(address, list.ToArray());
}
}
else if (type == typeof(ushort[]) || type == typeof(List<ushort>))
{
if (data is ushort[] arr)
{
resultdata = plc.Write(address, arr);
}
else if (data is List<ushort> list)
{
//list
resultdata = plc.Write(address, list.ToArray());
}
}
else if (type == typeof(int[]) || type == typeof(List<int>))
{
if (data is int[] arr)
{
resultdata = plc.Write(address, arr);
}
else if (data is List<int> list)
{
//list
resultdata = plc.Write(address, list.ToArray());
}
}
else if (type == typeof(uint[]) || type == typeof(List<uint>))
{
if (data is uint[] arr)
{
resultdata = plc.Write(address, arr);
}
else if (data is List<uint> list)
{
//list
resultdata = plc.Write(address, list.ToArray());
}
}
else if (type == typeof(long[]) || type == typeof(List<long>))
{
if (data is long[] arr)
{
resultdata = plc.Write(address, arr);
}
else if (data is List<long> list)
{
//list
resultdata = plc.Write(address, list.ToArray());
}
}
else if (type == typeof(ulong[]) || type == typeof(List<ulong>))
{
if (data is ulong[] arr)
{
resultdata = plc.Write(address, arr);
}
else if (data is List<ulong> list)
{
//list
resultdata = plc.Write(address, list.ToArray());
}
}
else if (type == typeof(float[]) || type == typeof(List<float>))
{
if (data is float[] arr)
{
resultdata = plc.Write(address, arr);
}
else if (data is List<float> list)
{
//list
resultdata = plc.Write(address, list.ToArray());
}
}
else if (type == typeof(double[]) || type == typeof(List<double>))
{
if (data is double[] arr)
{
resultdata = plc.Write(address, arr);
}
else if (data is List<double> list)
{
//list
resultdata = plc.Write(address, list.ToArray());
}
}
else if (type == typeof(bool[]) || type == typeof(List<bool>))
{
if (data is bool[] arrb)
{
resultdata = plc.Write(address, arrb);
}
else if (data is List<bool> listb)
{
resultdata = plc.Write(address, listb.ToArray());
}
}
else if (type == typeof(byte[]) || type == typeof(List<byte>))
{
if (data is byte[] arrby)
{
resultdata = plc.Write(address, arrby);
}
else if (data is List<byte> listb)
{
resultdata = plc.Write(address, listb.ToArray());
}
}
else if (type == typeof(string))
{
if (data is string str)
{
resultdata = plc.Write(address, str, Encoding.ASCII);
}
}
}
catch (Exception ex)
{
IsConnect = false;
LogHelper.Instance.Error($"写PLC数据失败:{address},{ex}");
}
if (!resultdata.IsSuccess)
{
LogHelper.Instance.Error("写PLC数据失败:" + address);
}
return resultdata;
}
public bool CheckBytesEquals(byte[] a, byte[] b)
{
if (a == null || b == null) return false;
if (a.Length != b.Length) return false;
for (int i = 0; i < a.Length; i++)
{
if (a[i] != b[i])
{
return false;
}
}
return true;
}
//public Task TrigScriptAsync(ScriptEntity script, string funcJson)
//{
// //return Task.Run(() =>
// //{
// // return RunSrcipt(script, funcJson);
// //});
//}
//private OperateResult RunSrcipt(ScriptEntity script, string funcJson)
//{
// Stopwatch watch = new Stopwatch();
// watch.Start();
// try
// {
// //OperateResult result = ScriptEngine.RunScript(_unityContainer, funcJson, script);
// //LogHelper.Instance.Info($"脚本【{script.Name}】执行用时:" + watch.ElapsedMilliseconds + "ms");
// return null;
// }
// catch (Exception ex)
// {
// LogHelper.Instance.Error("脚本执行异常", ex);
// return null;
// }
//}
//public Task TrigServiceAsync(string serviceName, string fName, string funcJson)
//{
// return Task.Run(() =>
// {
// TrigService(serviceName, fName, funcJson);
// });
//}
public void TrigService(string serviceName, string fName, string funcJson)
{
Assembly asm = Assembly.GetExecutingAssembly();
Type type = asm.GetType($"Cowain.Bake.Communication.Service.{serviceName}");
var ts = _unityContainer.Resolve(type);
object[] parameters = new object[1];
parameters[0] = funcJson;
try
{
MethodInfo mt = ts.GetType().GetMethod(fName);
if (mt != null)
{
mt.Invoke(ts, parameters);
}
}
catch (Exception ex)
{
LogHelper.Instance.Error($"TrigService{ex}");
}
}
}
}

View File

@@ -0,0 +1,33 @@
using Cowain.Bake.Model.Models;
using Opc.Ua;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity;
namespace Cowain.Bake.Communication.PLC
{
public struct BlockData
{
public DataValue Data;
public Variable Node;
public BlockData(DataValue data, Variable node)
{
Data = data;
Node = node;
}
}
public class PLCBlockingCollection
{
IUnityContainer _unityContainer;
public BlockingCollection<BlockData> MsgBlock = new BlockingCollection<BlockData>();
public PLCBlockingCollection(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
}
}

View File

@@ -0,0 +1,96 @@
using Cowain.Bake.BLL;
using Cowain.Bake.Common;
using Cowain.Bake.Common.Core;
using Cowain.Bake.Common.Enums;
using Cowain.Bake.Common.Models;
using Cowain.Bake.Communication.Interface;
using Cowain.Bake.Model;
using Cowain.Bake.Model.Models;
using Prism.Ioc;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
using Unity;
namespace Cowain.Bake.Communication.PLC
{
public class PLCManage
{
IUnityContainer _unityContainer;
private List<TDeviceConfig> plcList;
public PLCManage(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
plcList = _unityContainer.Resolve<DeviceConfigService>().GetConfig(EDeviceType.PLC);
foreach (var item in plcList)
{
Assembly asm = Assembly.GetExecutingAssembly(); //获得当前程序的绝对路径
Type type = asm.GetType(MyPath.PLC + item.DriverName);
unityContainer.RegisterSingleton(typeof(IPLCDevice), type, item.Name);
var plc = _unityContainer.Resolve<IPLCDevice>(item.Name); //几个PLC就实例化几个
plc.Id = item.Id;
plc.Name = item.Name;
plc.DeviceName = item.DriverName;
plc.GetJsonParam(item.Json);
//2023.3.1修改不需要读取StorageList驱动自己分批读取
var plcTagList = _unityContainer.Resolve<TagListService>().GetTagList(item.Id); //获取PLC的标签和节点
if (plcTagList != null && plcTagList.Count > 0)
{
int q = 0;
plcTagList.ForEach((x) =>
{
plc.TagList.Add(x);
plc.VariableList.Add(new Variable()
{
Id = (int)x.Id,
Quality = false,
VarType = x.VarType,
ArrayLength = x.ArrayLen,
StationId = x.StationId,
ParamName = x.ParamName,
Number = x.Number,
Index = q++,
TrigEnable = x.TirgEnable,
TrigJson = x.TrigJson,
OperType = x.OperType.Value,
Json = x.Json,
VarDesc = x.VarDesc,
VarName = x.VarName,
Address = x.Address,
TagType = x.TagType
});
});
foreach (var v in plc.VariableList)
{
if (!plc.VariableDic.ContainsKey(v.Id))
{
plc.VariableDic.Add(v.Id, v);
}
else
{
LogHelper.Instance.Error($"PLC有相同的节点,Node=[{v.VarName}]");
}
}
}
if (item.Enable)
{
plc.AnalysisAddress(); //把地址拆开,并计算长度
plc.GetStorageArea(); //获取存储区域
//plc.Connect();
//plc.StartRead();
Task t = new Task(() => //var t = Task.Run(async delegate
{
plc.Connect();
});
plc.StartRead();
}
}
}
}
}

View File

@@ -0,0 +1,109 @@
using Cowain.Bake.BLL;
using Cowain.Bake.Common;
using Cowain.Bake.Common.Core;
using HslCommunication;
using HslCommunication.Core;
using HslCommunication.ModBus;
using Newtonsoft.Json;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Unity;
using Hsl = HslCommunication.Profinet.Omron;
namespace Cowain.Bake.Communication.PLC
{
public class PLC_ModbusTcp : PLCBase
{
public override int Port { get; set; } = 502;
private ModbusTcpNet plc;
public PLC_ModbusTcp(IUnityContainer unityContainer, IDialogService dialogService) : base(unityContainer, dialogService)
{
}
public override void Close()
{
IsConnect = false;
try
{
plc?.ConnectClose();
plc?.Dispose();
plc = null;
}
catch (Exception ex)
{
LogHelper.Instance.Error($"关闭PLC连接失败{ex}");
}
}
public override void Connect()
{
Close();
if (plc == null)
{
plc = new ModbusTcpNet();
this.PLC = plc;
this.ByteTransform = plc.ByteTransform;
plc.ConnectTimeOut = 3000;
}
try
{
plc.IpAddress = this.IpAddress;
plc.Port = this.Port;
plc.ByteTransform.DataFormat = HslCommunication.Core.DataFormat.CDAB;
var result = plc.ConnectServer();
if (result.IsSuccess)
{
IsConnect = true;
}
else
{
IsConnect = false;
LogHelper.Instance.Error("连接PLC失败,请检查网络和参数");
}
}
catch (Exception ex)
{
IsConnect = false;
LogHelper.Instance.Error($"连接PLC失败{ex}");
}
}
public override void GetJsonParam(string param)
{
dynamic d = JsonConvert.DeserializeObject<dynamic>(param);
this.IpAddress = d.Ip;
this.Port = d.Port;
}
public override void GetReadAddress()
{
foreach (var storage in Storages)
{
storage.ReadAddress = storage.AddressType + ";" + storage.StartAddress;
}
}
public override OperateResult Write<T>(string address, T data, int maxCount = 5)
{
return Write<T>(plc, address, data, maxCount);
}
public override OperateResult Writes(string[] tags, object[] values, int maxCount = Global.MAX_READS)
{
return null;
}
}
}

View File

@@ -0,0 +1,126 @@
using Cowain.Bake.BLL;
using Cowain.Bake.Communication.Interface;
using Cowain.Bake.Common.Models;
using HslCommunication;
using Newtonsoft.Json;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Unity;
using Hsl = HslCommunication.Profinet.Omron;
using Cowain.Bake.Model.Entity;
using Cowain.Bake.Common.Core;
using Cowain.Bake.Common;
namespace Cowain.Bake.Communication.PLC
{
public class PLC_OmronFins : PLCBase
{
public override int Port { get; set; } = 9600;
private Hsl.OmronFinsNet plc;
public PLC_OmronFins(IUnityContainer unityContainer, IDialogService dialogService) : base(unityContainer, dialogService)
{
}
public override void Close()
{
IsConnect = false;
try
{
plc?.ConnectClose();
plc?.Dispose();
plc = null;
}
catch (Exception ex)
{
LogHelper.Instance.Error($"关闭PLC连接失败{ex}");
}
}
public override void Connect()
{
Close();
if (plc == null)
{
//HslCommunication.Profinet.OpenProtocol aa = new HslCommunication.Profinet.OpenProtocol();
plc = new Hsl.OmronFinsNet();
this.PLC = plc;
this.ByteTransform = plc.ByteTransform;
plc.ConnectTimeOut = 3000;
//plc.SetPersistentConnection();
}
try
{
plc.IpAddress = this.IpAddress;
plc.Port = this.Port;
plc.SA1 = 0;
plc.DA2 = this.Slot;
plc.ByteTransform.DataFormat = HslCommunication.Core.DataFormat.CDAB;
var result = plc.ConnectServer();
if (result.IsSuccess)
{
IsConnect = true;
}
else
{
IsConnect = false;
LogHelper.Instance.Error("连接PLC失败,请检查网络和参数");
}
}
catch (Exception ex)
{
IsConnect = false;
LogHelper.Instance.Error($"连接PLC失败{ex}");
}
}
public override void GetJsonParam(string param)
{
dynamic d = JsonConvert.DeserializeObject<dynamic>(param);
this.IpAddress = d.Ip;
this.Port = d.Port;
this.Slot = d.Slot;
}
public override void AddressSplit(TagEntity tag)
{
//格式:D100,C100,W100,H100
Match m = Regex.Match(tag.Address, @"[a-zA-Z]{1}[0-9]+", RegexOptions.Singleline);
if (m.Success)
{
VariableDic[(int)tag.Id].AddressType = m.Value.Substring(0, 1);
VariableDic[(int)tag.Id].Address = m.Value.Substring(1);
}
}
public override void GetReadAddress()
{
foreach (var storage in Storages)
{
storage.ReadAddress = storage.AddressType + storage.StartAddress;
}
}
public override OperateResult Write<T>(string address, T data, int maxCount = Global.MAX_READS)
{
return Write<T>(plc, address, data, maxCount);
}
public override OperateResult Writes(string[] tags, object[] values, int maxCount = Global.MAX_READS)
{
return null;
}
}
}

View File

@@ -0,0 +1,682 @@
using Cowain.Bake.BLL;
using Cowain.Bake.Common;
using Cowain.Bake.Common.Core;
using Cowain.Bake.Common.Enums;
using Cowain.Bake.Common.Interface;
using Cowain.Bake.Model.Entity;
using Cowain.Bake.Model.Models;
using HslCommunication;
using Newtonsoft.Json;
using Opc.Ua;
using Opc.Ua.Client;
using OpcUaHelper;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Unity;
namespace Cowain.Bake.Communication.PLC
{
public class PLC_OpcUaClient : PLCBase
{
readonly static object _objLock = new object();
readonly CancellationTokenSource cts = new CancellationTokenSource();
bool isSubscribeNodes = false;
public OpcUaClient opcUaClient { get; set; }
ITrigService _trigService { get; set; }
public PLC_OpcUaClient(IUnityContainer unityContainer, IDialogService dialogService) : base(unityContainer, dialogService)
{
opcUaClient = new OpcUaClient();
OPC = opcUaClient;
opcUaClient.ConnectComplete += OpcUaClient_ConnectComplete;
opcUaClient.KeepAliveComplete += OpcUaClient_KeepAliveComplete;
opcUaClient.ReconnectStarting += OpcUaClient_ReconnectStarting;
opcUaClient.ReconnectComplete += OpcUaClient_ReconnectComplete;
opcUaClient.OpcStatusChange += OpcUaClient_OpcStatusChange;
_trigService = _unityContainer.Resolve<ITrigService>(); //MachinePLCService
//Start();
}
~PLC_OpcUaClient()
{
Close();
Stop();
}
public void Start()
{
Task.Run(async () =>
{
while (!cts.Token.IsCancellationRequested)
{
if (Global.AppExit)
{
return;
}
await Task.Delay(Global.HEARTBEAT_INTERVAL_TIME);
if (null == opcUaClient || !opcUaClient.Connected || !IsConnect)
{
continue;
}
var node = (from secondaryList in Storages
from item in secondaryList.VariableList
where item.ParamName == EStoveSignal.Heartbeat.ToString()
orderby item.Number
select item).FirstOrDefault();
if (null == node)
{
LogHelper.Instance.Warn("查询心跳节点失败");
continue;
}
OperateResult result = Write<UInt16>(node.Address + node.VarName, 1);
if (!result.IsSuccess)
{
LogHelper.Instance.Warn($"MachineId:{Storages[0].StationId}:写心跳节点失败");
}
}
}, cts.Token);
}
public void Stop()
{
cts.Cancel();
}
/// <summary>
/// 连接服务器结束后马上浏览根节点
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OpcUaClient_ConnectComplete(object sender, EventArgs e)
{
try
{
opcUaClient = (OpcUaClient)sender; //2.重连不成功
OPC = opcUaClient;
IsConnect = opcUaClient.Connected;
if (!isSubscribeNodes
&& IsConnect
&& !Global.AppExit)
{
opcUaClient.RemoveAllSubscription();
isSubscribeNodes = true;
//SubscribeNodes(); //订阅节点
SubscriptionNodes();
CheckAddress(); //add by lsm 20260203
LogHelper.Instance.Fatal($"{ConnectString},订阅节点");
}
}
catch (Exception exception)
{
IsConnect = false;
LogHelper.Instance.Error($"订阅失败!,{ConnectString},{exception}");
}
}
void CheckAddress()
{
foreach (var storage in Storages)
{
foreach (var item in storage.OPCNodes)
{
DataValue values1 = opcUaClient.ReadNode(item);
if (values1 == null || null == values1.Value
|| null == values1.WrappedValue.Value
|| !StatusCode.IsGood(values1.StatusCode))
{
LogHelper.Instance.Debug($"{ConnectString},读取失败:{item}");
}
}
}
}
private void OpcUaClient_OpcStatusChange(object sender, OpcUaStatusEventArgs e)
{
try
{
if (e.Error) //1.重连不成功
{
IsConnect = false;
LogHelper.Instance.Warn($"OPC UA客户端重连不成功{e.Text}");
}
if (!Regex.IsMatch(e.Text, "Connected"))
{
LogHelper.Instance.Info($"本OPC UA客户端的终极事件,{IpAddress}{e.Text}");
}
}
catch (Exception ex)
{
LogHelper.Instance.Error($"OpcUaClient_OpcStatusChange:" + ex.Message);
//throw;
}
//if (Regex.IsMatch(e.Text, "Reconnecting")) //验证无效
//{
// opcUaClient.Session.Reconnect();
//}
//LogHelper.Instance.Info("本OPC UA客户端的终极事件当客户端的状态变更都会触发包括了连接重连断开状态激活:" + e.ToString());
}
private void OpcUaClient_ReconnectComplete(object sender, EventArgs e)
{
LogHelper.Instance.Info("重新连接到服务器的时候触发");
}
private void OpcUaClient_ReconnectStarting(object sender, EventArgs e)
{
LogHelper.Instance.Info($"开始重新连接到服务器的时候触发,{IpAddress}");
}
private void OpcUaClient_KeepAliveComplete(object sender, EventArgs e)
{
//LogHelper.Instance.Debug("ua客户端每隔5秒会与服务器进行通讯验证每次验证都会触发该方法");
}
public async override void Connect()
{
try
{
if (null != opcUaClient.Session)
{
//如果session没问题能关掉为什么要重连呢,230606
Close();
}
//var timeouttask = Task.Delay(3000);
//var completedTask = await Task.WhenAny(opcUaClient.ConnectServer(ConnectString), timeouttask);
opcUaClient.UserIdentity = new UserIdentity(new AnonymousIdentityToken());
await opcUaClient.ConnectServer(ConnectString);
opcUaClient.ReconnectPeriod = 20000; //OPC UA 客户端在与服务器断开连接后尝试重新连接的时间间隔,是一个表示时间间隔的数值,以毫秒为单位
if (null != opcUaClient.Session)
{
opcUaClient.Session.OperationTimeout = 5000; // 执行操作时的超时时间。它指定了客户端等待服务器响应的最长时间,以毫秒为单位
}
LogHelper.Instance.Fatal($"连接OPCUA服务器,{ConnectString}");
//if (completedTask == timeouttask)
//{
// LogHelper.Instance.Error("连接OPCUA服务器超时");
//}
}
catch (Exception ex)
{
LogHelper.Instance.Error($"连接OPCUA服务器失败Connect:{ConnectString},{ex.Message}");
}
}
public override void Close()
{
if (null != opcUaClient.Session)
{
IsConnect = false;
isSubscribeNodes = false;
opcUaClient?.RemoveAllSubscription();
opcUaClient?.Disconnect();
LogHelper.Instance.Fatal($"Close:{ConnectString},订阅删除");
}
}
public override void StartRead()
{
base.StartRead();
}
/// <summary>
/// 把地址拆开x=3;11 OPC是节点可以不要
/// new用于隐藏方法它调用的方法来自于申明的类
/// </summary>
public override void AnalysisAddress()
{
}
public override void GetStorageArea()
{
Storages.Clear();
var query = (from v in VariableList //Regex.Replace(v.VarType, @"\[.*\]", string.Empty)
orderby v.Id // Convert.ToInt16(v.Address), v.ReadLength
group v by new { v.StationId, v.VarType } //new {v.DeviceId, v.VarType} //按读的数据类型分组 Regex.Replace(v.VarType, @"\[.*\]", string.Empty
into a
where a.Count() > 0
orderby a.Key.StationId
select a).ToList();
foreach (var g in query)
{
//var first = g.First();
var totalLengthQuery = (from a in g //同类型,同大小的分一组,单个和数组各一组,
orderby a.ArrayLength
group a by a.ArrayLength > 1 into b //a.VarType.Substring(a.VarType.Length - 1)
select new
{
VarList = b,
Id = b.First().Id,
StationId = b.First().StationId,
AddressType = b.First().VarType,
//StartAddress = b.First().ReadLength, //这样第一次偏移永远是0
GroupReadLength = b.Sum(t => t.ArrayLength)
}).ToList();
totalLengthQuery.ForEach(x =>
{
List<string> nodes = new List<string>();
List<Variable> variables = x.VarList.ToList();
var readNode = variables.Where(ns => ns.OperType != (int)EOperTypePLC.Writable).ToList();
foreach (var variable in readNode)
{
nodes.Add($"{variable.Address}{variable.VarName}");
}
Storages.Add(new StorageArea()
{
Id = x.Id,
StationId = x.StationId,
AddressType = x.AddressType,
//StartAddress = x.StartAddress.ToString(),
OPCNodes = nodes,
Len = x.GroupReadLength, //如何判断是不是数组
VariableList = variables
});
});
}
}
public override void GetJsonParam(string param)
{
dynamic d = JsonConvert.DeserializeObject<dynamic>(param);
this.ConnectString = d.ConnectString;
}
//public byte[] TToByte<T>(T[] value)
//{
// string typeName = value.GetType().FullName.Replace("[]", string.Empty);
// Type type = Type.GetType(typeName); //System.UInt16
// int size = Marshal.SizeOf(type);
// byte[] result = new byte[value.Length * size];
// Buffer.BlockCopy(value, 0, result, 0, result.Length);
// return result;
//}
public override OperateResult<T> Read<T>(string tag)
{
OperateResult<T> operateResult = new OperateResult<T>()
{
IsSuccess = false,
};
if (!opcUaClient.Connected)
{
return operateResult;
}
operateResult.Content = opcUaClient.ReadNode<T>(tag);
if (null != operateResult.Content)
{
operateResult.IsSuccess = true;
}
return operateResult;
}
/// <summary>
/// 读多个节点,返回的数据类型相同 item.OPCNodes, item.AddressType, (item.VariableList[0].ArrayLength > 1) ? true : false
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="nodes"></param>
/// <param name="len"></param>
/// <returns></returns>
public OperateResult<bool> ReadNode(StorageArea storage)
{
//opcUaClient.ReadNode 读单个未知数据类型
//opcUaClient.ReadNode<> 读单个已知数据类型; 也可以是个数组地址,返回一个数组(同类型)
//opcUaClient.ReadNodes 读多个节点数据,可以是多个不同类型的数据;一个节点一个Object,返回object列表,1对1的关系
//opcUaClient.ReadNodes<> 读多个节点数据,同一类型,返回一个数组
//MethodInfo mi = null;
bool result;
OperateResult<bool> operateResult = new OperateResult<bool>()
{
IsSuccess = false,
Content = false,
};
result = Read(storage);
operateResult.IsSuccess = result;
operateResult.Content = result;
return operateResult;
}
public override List<DataValue> Reads(NodeId[] nodeIds)
{
return opcUaClient.ReadNodes(nodeIds);
}
public bool Read(StorageArea storage)
{
int index = 0;
List<NodeId> nodeIds = new List<NodeId>();
foreach (var item in storage.OPCNodes)
{
nodeIds.Add(new NodeId(item));
}
if (0 == nodeIds.Count
|| Global.AppExit
|| !opcUaClient.Connected)
{
return true;
}
try
{
List<DataValue> values = opcUaClient.ReadNodes(nodeIds.ToArray());
var readNode = storage.VariableList.Where(ns => ns.OperType != (int)EOperTypePLC.Writable).ToList();
foreach (var node in readNode)
{
if (values[index] == null || null == values[index].Value
|| null == values[index].WrappedValue.Value
|| !StatusCode.IsGood(values[index].StatusCode))
{
node.Quality = false;
//LogHelper.Instance.Error($"读取节点数据失败,{node.VarName},{node.VarDesc}");
//_unityContainer.Resolve<LogService>().AddLog($"PLC_OpcUaClient:Read:读取节点数据失败,{node.VarName},{node.VarDesc}", E_LogType.Info.ToString());
return false;
}
else
{
node.CurValue = values[index].WrappedValue.Value;
node.Value = ShowValue(values[index]);
node.Quality = true;
}
index++;
}
}
catch (Exception ex)
{
string json = JsonConvert.SerializeObject(storage.OPCNodes.ToArray());
LogHelper.Instance.Fatal($"读取节点,DeviceId:【{json}】报错," + ex.Message);
return false;
}
return true;
}
public object ShowValue(DataValue value)
{
if (value.WrappedValue.TypeInfo.ValueRank == -1)
{
return value.WrappedValue.Value;
}
if (value.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.Int32)
{
return string.Join("|", (int[])value.WrappedValue.Value); // 最终值
}
else if (value.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.UInt32)
{
return string.Join("|", (uint[])value.WrappedValue.Value); // 数组的情况参照上面的例子
}
else if (value.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.Float)
{
return string.Join("|", (float[])value.WrappedValue.Value); // 数组的情况参照上面的例子
}
else if (value.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.Boolean)
{
return string.Join("|", (bool[])value.WrappedValue.Value); // 数组的情况参照上面的例子
}
else if (value.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.UInt16)
{
return string.Join("|", (UInt16[])value.WrappedValue.Value); // 数组的情况参照上面的例子
}
else if (value.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.Int16)
{
return string.Join("|", (Int16[])value.WrappedValue.Value); // 数组的情况参照上面的例子
}
else
{
return "None";
}
}
public override void ReadStorageArea()
{
bool readError = false;
OperateResult<bool> read;
foreach (var item in Storages)
{
for (int i = 0; i < Global.MAX_READS; i++)
{
if (Global.AppExit)
{
return;
}
read = ReadNode(item);
if (read.IsSuccess)
{
IsConnect = true;
readError = false;
break;
}
else
{
foreach (var val in item.VariableList)
{
val.Quality = false;
}
//LogHelper.Instance.Error($"{ConnectString},ErrorCode:{read.ErrorCode},读错误:" + read.Message);
}
readError = true;
//由于此处是不停的根据表中的配置刷新数据的OPC UA建立security channel的成本很高所以必须限制此处的时间
//给其他线程的读写留出空余时间
Thread.Sleep(199);
}
Thread.Sleep(199);
if (readError)
{
//230605
//IsConnect = false;
//break;
}
}
// 触发 GC
GC.Collect();
GC.WaitForPendingFinalizers();
}
//上下料
public override OperateResult<T> GetValue<T>(string paramName)
{
string msg = "";
OperateResult<T> result = new OperateResult<T>()
{
IsSuccess = false,
};
Variable node = (from storage in Storages
from item in storage.VariableList
where item.ParamName == paramName
select item).FirstOrDefault();
if (null == node || null == node.CurValue)
{
msg = $"获取内存PLC数据失败paramName:{paramName}";
result.Message = msg;
return result;
}
else
{
result.Content = (T)Convert.ChangeType(node.CurValue, typeof(T));
result.IsSuccess = true;
return result;
}
}
public override Variable GetVariable(string paramName, int machineId, int number = 0)
{
Variable node = (from storage in Storages
from item in storage.VariableList
where storage.StationId == machineId && item.ParamName == paramName && item.Number == number
select item).FirstOrDefault();
if (null == node)
{
LogHelper.Instance.GetCurrentClassError("没有找到这个节点信息");
}
return node;
}
public override OperateResult<T> GetValue<T>(string paramName, int stationId, int number = 1)
{
string msg = "";
OperateResult<T> result = new OperateResult<T>()
{
IsSuccess = false,
};
Variable node = (from storage in Storages
from item in storage.VariableList
where storage.StationId == stationId && item.ParamName == paramName && item.Number == number
select item).FirstOrDefault();
if (null == node || null == node.CurValue)
{
LogHelper.Instance.Error($"没有节点信息:{paramName},工站:{stationId},number:{number}");
msg = $"获取内存PLC数据失败addr:{node.Address}{node.VarName}number:{number},{stationId}";
result.Message = msg;
return result;
}
else
{
result.Content = (T)Convert.ChangeType(node.CurValue, typeof(T));
result.IsSuccess = true;
return result;
}
}
//可以发送多个地址
public override OperateResult Writes(string[] tags, object[] values, int maxCount = Global.MAX_READS)
{
OperateResult result = new OperateResult()
{
IsSuccess = false
};
try
{
for (int i = 0; i < maxCount; i++)
{
result.IsSuccess = opcUaClient.WriteNodes(tags, values); //现在不能写,因为
if (result.IsSuccess)
{
break;
}
Thread.Sleep(100);
}
//写不成功就断开链接暂时屏蔽针对OPC UA因为重建session需要成本太大
//230605
//IsConnect = false;
//出异常再捕获,写不成功暂时不捕获
//LogHelper.Instance.Info($"写数据失败,节点 = {tags.ToString()},值={values.ToString()}");
}
catch (Exception ex)
{
LogHelper.Instance.Error($"写数据失败,节点 = {tags},值={values},失败原因:{ex}");
_unityContainer.Resolve<LogService>().AddLog($"PLC_OpcUaClient:写数据失败,节点 = {tags},值={values}", E_LogType.Error.ToString());
}
return result;
}
//T:可以为数组
public override OperateResult Write<T>(string address, T data, int maxCount = Global.MAX_READS)
{
OperateResult result = new OperateResult()
{
IsSuccess = false
};
try
{
for (int i = 0; i < maxCount; i++)
{
if (!opcUaClient.Connected)
{
return result;
}
result.IsSuccess = opcUaClient.WriteNode<T>(address, data); //现在不能写,因为
if (result.IsSuccess)
{
break;
//return result;
}
Thread.Sleep(199);
}
//230605
//IsConnect = false;
//LogHelper.Instance.Info($"写数据失败,节点 = {address},值={data.ToString()}");
}
catch (Exception ex)
{
LogHelper.Instance.Error($"写数据失败,节点 = {address},值={data},失败原因:{ex}");
_unityContainer.Resolve<LogService>().AddLog($"PLC_OpcUaClient:Write:写数据失败,节点 = {address},值={data},失败原因:" + ex.Message, E_LogType.Error.ToString());
}
return result;
}
public void SubscriptionNodes()
{
List<Variable> SubInfoNodes = (from v in VariableList
orderby v.Index
where v.TrigEnable == true //按读的数据类型分组 炉子有42个信号
select v).ToList();
foreach (var item in SubInfoNodes)
{
string vkey = $"{item.Id}";
string nodeId = $"{item.Address}{item.VarName}";
SingleNodeIdDatasSubscription(vkey, nodeId, (key, monitoredItem, args) =>
{
if (vkey == key)
{
MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;
if (notification != null)
{
item.Quality = StatusCode.IsGood(notification.Value.StatusCode);
if (item.Quality)
{
_unityContainer.Resolve<PLCBlockingCollection>().MsgBlock.Add(new BlockData(notification.Value, item));
}
}
}
});
}
}
/// <summary>
/// 单节点数据订阅
/// </summary>
/// <param name="key">订阅的关键字(必须唯一)</param>
/// <param name="nodeId">节点:"ns=3;s=\"test\".\"Static_1\""</param>
/// <param name="callback">数据订阅的回调方法</param>
public void SingleNodeIdDatasSubscription(string key, string nodeId, Action<string, Opc.Ua.Client.MonitoredItem, MonitoredItemNotificationEventArgs> callback)
{
if (opcUaClient == null) return;
try
{
opcUaClient.AddSubscription(key, nodeId, callback);
}
catch (Exception ex)
{
LogHelper.Instance.Error($"订阅节点异常:{nodeId},Msg={ex.Message}");
}
}
}
}

View File

@@ -0,0 +1,715 @@
using Cowain.Bake.BLL;
using Cowain.Bake.Common;
using Cowain.Bake.Common.Core;
using Cowain.Bake.Common.Enums;
using Cowain.Bake.Common.Interface;
using Cowain.Bake.Model.Entity;
using Cowain.Bake.Model.Models;
using HslCommunication;
using Newtonsoft.Json;
using Opc.Ua;
using Opc.Ua.Client;
using OpcUaHelper;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Unity;
namespace Cowain.Bake.Communication.PLC
{
public class PLC_OpcUaClient : PLCBase
{
readonly static object _objLock = new object();
readonly CancellationTokenSource cts = new CancellationTokenSource();
bool isSubscribeNodes = false;
public OpcUaClient opcUaClient { get; set; }
ITrigService _trigService { get; set; }
public PLC_OpcUaClient(IUnityContainer unityContainer, IDialogService dialogService) : base(unityContainer, dialogService)
{
opcUaClient = new OpcUaClient();
OPC = opcUaClient;
opcUaClient.ConnectComplete += OpcUaClient_ConnectComplete;
opcUaClient.KeepAliveComplete += OpcUaClient_KeepAliveComplete;
opcUaClient.ReconnectStarting += OpcUaClient_ReconnectStarting;
opcUaClient.ReconnectComplete += OpcUaClient_ReconnectComplete;
opcUaClient.OpcStatusChange += OpcUaClient_OpcStatusChange;
_trigService = _unityContainer.Resolve<ITrigService>(); //MachinePLCService
//Start();
}
~PLC_OpcUaClient()
{
Close();
Stop();
}
public void Start()
{
Task.Run(async () =>
{
while (!cts.Token.IsCancellationRequested)
{
if (Global.AppExit)
{
return;
}
await Task.Delay(Global.HEARTBEAT_INTERVAL_TIME);
if (null == opcUaClient || !opcUaClient.Connected || !IsConnect)
{
continue;
}
var node = (from secondaryList in Storages
from item in secondaryList.VariableList
where item.ParamName == EStoveSignal.Heartbeat.ToString()
orderby item.Number
select item).FirstOrDefault();
if (null == node)
{
LogHelper.Instance.Warn("查询心跳节点失败");
continue;
}
OperateResult result = Write<UInt16>(node.Address + node.VarName, 1);
if (!result.IsSuccess)
{
LogHelper.Instance.Warn($"MachineId:{Storages[0].StationId}:写心跳节点失败");
}
}
}, cts.Token);
}
public void Stop()
{
cts.Cancel();
}
/// <summary>
/// 连接服务器结束后马上浏览根节点
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OpcUaClient_ConnectComplete(object sender, EventArgs e)
{
try
{
opcUaClient = (OpcUaClient)sender; //2.重连不成功
OPC = opcUaClient;
IsConnect = opcUaClient.Connected;
if (!isSubscribeNodes
&& IsConnect
&& !Global.AppExit)
{
opcUaClient.RemoveAllSubscription();
isSubscribeNodes = true;
SubscribeNodes(); //订阅节点
LogHelper.Instance.Fatal($"{ConnectString},订阅节点");
}
}
catch (Exception exception)
{
IsConnect = false;
LogHelper.Instance.Error($"订阅失败!,{ConnectString},{exception}");
}
}
private void OpcUaClient_OpcStatusChange(object sender, OpcUaStatusEventArgs e)
{
try
{
if (e.Error) //1.重连不成功
{
IsConnect = false;
LogHelper.Instance.Warn($"OPC UA客户端重连不成功{e.Text}");
}
if (!Regex.IsMatch(e.Text, "Connected"))
{
LogHelper.Instance.Info($"本OPC UA客户端的终极事件,{IpAddress}{e.Text}");
}
}
catch (Exception ex)
{
LogHelper.Instance.Error($"OpcUaClient_OpcStatusChange:" + ex.Message);
//throw;
}
//if (Regex.IsMatch(e.Text, "Reconnecting")) //验证无效
//{
// opcUaClient.Session.Reconnect();
//}
//LogHelper.Instance.Info("本OPC UA客户端的终极事件当客户端的状态变更都会触发包括了连接重连断开状态激活:" + e.ToString());
}
private void OpcUaClient_ReconnectComplete(object sender, EventArgs e)
{
LogHelper.Instance.Info("重新连接到服务器的时候触发");
}
private void OpcUaClient_ReconnectStarting(object sender, EventArgs e)
{
LogHelper.Instance.Info($"开始重新连接到服务器的时候触发,{IpAddress}");
}
private void OpcUaClient_KeepAliveComplete(object sender, EventArgs e)
{
//LogHelper.Instance.Debug("ua客户端每隔5秒会与服务器进行通讯验证每次验证都会触发该方法");
}
public async override void Connect()
{
try
{
if (null != opcUaClient.Session)
{
//如果session没问题能关掉为什么要重连呢,230606
Close();
}
//var timeouttask = Task.Delay(3000);
//var completedTask = await Task.WhenAny(opcUaClient.ConnectServer(ConnectString), timeouttask);
await opcUaClient.ConnectServer(ConnectString);
opcUaClient.ReconnectPeriod = 20000; //OPC UA 客户端在与服务器断开连接后尝试重新连接的时间间隔,是一个表示时间间隔的数值,以毫秒为单位
if (null != opcUaClient.Session)
{
opcUaClient.Session.OperationTimeout = 5000; // 执行操作时的超时时间。它指定了客户端等待服务器响应的最长时间,以毫秒为单位
}
LogHelper.Instance.Fatal($"连接OPCUA服务器,{ConnectString}");
//if (completedTask == timeouttask)
//{
// LogHelper.Instance.Error("连接OPCUA服务器超时");
//}
}
catch (Exception ex)
{
LogHelper.Instance.Error($"连接OPCUA服务器失败Connect:{ConnectString},{ex.Message}");
}
}
public override void Close()
{
if (null != opcUaClient.Session)
{
IsConnect = false;
isSubscribeNodes = false;
opcUaClient.RemoveAllSubscription(); //
opcUaClient.Disconnect();
LogHelper.Instance.Fatal($"Close:{ConnectString},订阅删除");
}
}
public override void StartRead()
{
base.StartRead();
}
/// <summary>
/// 把地址拆开x=3;11 OPC是节点可以不要
/// new用于隐藏方法它调用的方法来自于申明的类
/// </summary>
public override void AnalysisAddress()
{
}
public override void GetStorageArea()
{
Storages.Clear();
var query = (from v in VariableList //Regex.Replace(v.VarType, @"\[.*\]", string.Empty)
orderby v.Id // Convert.ToInt16(v.Address), v.ReadLength
group v by new { v.StationId, v.VarType } //new {v.DeviceId, v.VarType} //按读的数据类型分组 Regex.Replace(v.VarType, @"\[.*\]", string.Empty
into a
where a.Count() > 0
orderby a.Key.StationId
select a).ToList();
foreach (var g in query)
{
//var first = g.First();
var totalLengthQuery = (from a in g //同类型,同大小的分一组,单个和数组各一组,
orderby a.ArrayLength
group a by a.ArrayLength > 1 into b //a.VarType.Substring(a.VarType.Length - 1)
select new
{
VarList = b,
Id = b.First().Id,
StationId = b.First().StationId,
AddressType = b.First().VarType,
//StartAddress = b.First().ReadLength, //这样第一次偏移永远是0
GroupReadLength = b.Sum(t => t.ArrayLength)
}).ToList();
totalLengthQuery.ForEach(x =>
{
List<string> nodes = new List<string>();
List<Variable> variables = x.VarList.ToList();
var readNode = variables.Where(ns => ns.OperType != (int)EOperTypePLC.Writable).ToList();
foreach (var variable in readNode)
{
nodes.Add($"{variable.Address}{variable.VarName}");
}
Storages.Add(new StorageArea()
{
Id = x.Id,
StationId = x.StationId,
AddressType = x.AddressType,
//StartAddress = x.StartAddress.ToString(),
OPCNodes = nodes,
Len = x.GroupReadLength, //如何判断是不是数组
VariableList = variables
});
});
}
}
public override void GetJsonParam(string param)
{
dynamic d = JsonConvert.DeserializeObject<dynamic>(param);
this.ConnectString = d.ConnectString;
}
//public byte[] TToByte<T>(T[] value)
//{
// string typeName = value.GetType().FullName.Replace("[]", string.Empty);
// Type type = Type.GetType(typeName); //System.UInt16
// int size = Marshal.SizeOf(type);
// byte[] result = new byte[value.Length * size];
// Buffer.BlockCopy(value, 0, result, 0, result.Length);
// return result;
//}
public override OperateResult<T> Read<T>(string tag)
{
OperateResult<T> operateResult = new OperateResult<T>()
{
IsSuccess = false,
};
if (!opcUaClient.Connected)
{
return operateResult;
}
operateResult.Content = opcUaClient.ReadNode<T>(tag);
if (null != operateResult.Content)
{
operateResult.IsSuccess = true;
}
return operateResult;
}
/// <summary>
/// 读多个节点,返回的数据类型相同 item.OPCNodes, item.AddressType, (item.VariableList[0].ArrayLength > 1) ? true : false
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="nodes"></param>
/// <param name="len"></param>
/// <returns></returns>
public OperateResult<bool> ReadNode(StorageArea storage)
{
//opcUaClient.ReadNode 读单个未知数据类型
//opcUaClient.ReadNode<> 读单个已知数据类型; 也可以是个数组地址,返回一个数组(同类型)
//opcUaClient.ReadNodes 读多个节点数据,可以是多个不同类型的数据;一个节点一个Object,返回object列表,1对1的关系
//opcUaClient.ReadNodes<> 读多个节点数据,同一类型,返回一个数组
//MethodInfo mi = null;
bool result;
OperateResult<bool> operateResult = new OperateResult<bool>()
{
IsSuccess = false,
Content = false,
};
result = Read(storage);
operateResult.IsSuccess = result;
operateResult.Content = result;
return operateResult;
}
public override List<DataValue> Reads(NodeId[] nodeIds)
{
return opcUaClient.ReadNodes(nodeIds);
}
public bool Read(StorageArea storage)
{
int index = 0;
List<NodeId> nodeIds = new List<NodeId>();
foreach (var item in storage.OPCNodes)
{
nodeIds.Add(new NodeId(item));
}
//------------------------------------------- add by lsm 20250925
//foreach (var item in storage.OPCNodes)
//{
// DataValue values1 = opcUaClient.ReadNode(item);
// if (values1 == null || null == values1.Value
// || null == values1.WrappedValue.Value
// || !StatusCode.IsGood(values1.StatusCode))
// {
// LogHelper.Instance.Error($"读取失败:{item}");
// //_unityContainer.Resolve<LogService>().AddLog($"PLC_OpcUaClient:Read:读取节点数据失败,{node.VarName},{node.VarDesc}", E_LogType.Info.ToString());
// }
// else
// {
// int kkk = 0;
// }
//}
//LogHelper.Instance.Debug($"-----end----------");
//-------------------------------------------
if (0 == nodeIds.Count
|| Global.AppExit
|| !opcUaClient.Connected)
{
return true;
}
try
{
List<DataValue> values = opcUaClient.ReadNodes(nodeIds.ToArray());
var readNode = storage.VariableList.Where(ns => ns.OperType != (int)EOperTypePLC.Writable).ToList();
foreach (var node in readNode)
{
if (values[index] == null || null == values[index].Value
|| null == values[index].WrappedValue.Value
|| !StatusCode.IsGood(values[index].StatusCode))
{
node.Quality = false;
//LogHelper.Instance.Error($"读取节点数据失败,{node.VarName},{node.VarDesc}");
//_unityContainer.Resolve<LogService>().AddLog($"PLC_OpcUaClient:Read:读取节点数据失败,{node.VarName},{node.VarDesc}", E_LogType.Info.ToString());
return false;
}
else
{
node.CurValue = values[index].WrappedValue.Value;
node.Value = ShowValue(values[index]);
node.Quality = true;
}
index++;
}
}
catch (Exception ex)
{
string json = JsonConvert.SerializeObject(storage.OPCNodes.ToArray());
LogHelper.Instance.Fatal($"读取节点,DeviceId:【{json}】报错," + ex.Message);
return false;
}
return true;
}
public object ShowValue(DataValue value)
{
if (value.WrappedValue.TypeInfo.ValueRank == -1)
{
return value.WrappedValue.Value;
}
if (value.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.Int32)
{
return string.Join("|", (int[])value.WrappedValue.Value); // 最终值
}
else if (value.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.UInt32)
{
return string.Join("|", (uint[])value.WrappedValue.Value); // 数组的情况参照上面的例子
}
else if (value.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.Float)
{
return string.Join("|", (float[])value.WrappedValue.Value); // 数组的情况参照上面的例子
}
else if (value.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.Boolean)
{
return string.Join("|", (bool[])value.WrappedValue.Value); // 数组的情况参照上面的例子
}
else if (value.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.UInt16)
{
return string.Join("|", (UInt16[])value.WrappedValue.Value); // 数组的情况参照上面的例子
}
else if (value.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.Int16)
{
return string.Join("|", (Int16[])value.WrappedValue.Value); // 数组的情况参照上面的例子
}
else
{
return "None";
}
}
public override void ReadStorageArea()
{
bool readError = false;
OperateResult<bool> read ;
foreach (var item in Storages)
{
for (int i = 0; i < Global.MAX_READS; i++)
{
if (Global.AppExit)
{
return;
}
read = ReadNode(item);
if (read.IsSuccess)
{
IsConnect = true;
readError = false;
break;
}
else
{
foreach (var val in item.VariableList)
{
val.Quality = false;
}
//LogHelper.Instance.Error($"{ConnectString},ErrorCode:{read.ErrorCode},读错误:" + read.Message);
}
readError = true;
//由于此处是不停的根据表中的配置刷新数据的OPC UA建立security channel的成本很高所以必须限制此处的时间
//给其他线程的读写留出空余时间
Thread.Sleep(199);
}
Thread.Sleep(199);
if (readError)
{
//230605
//IsConnect = false;
//break;
}
}
// 触发 GC
GC.Collect();
GC.WaitForPendingFinalizers();
}
//上下料
public override OperateResult<T> GetValue<T>(string paramName)
{
string msg = "";
OperateResult<T> result = new OperateResult<T>()
{
IsSuccess = false,
};
Variable node = (from storage in Storages
from item in storage.VariableList
where item.ParamName == paramName
select item).FirstOrDefault();
if (null == node || null == node.CurValue)
{
msg = $"获取内存PLC数据失败paramName:{paramName}";
result.Message = msg;
return result;
}
else
{
result.Content = (T)Convert.ChangeType(node.CurValue, typeof(T));
result.IsSuccess = true;
return result;
}
}
public override Variable GetVariable(string paramName, int machineId, int number = 0)
{
Variable node = (from storage in Storages
from item in storage.VariableList
where storage.StationId == machineId && item.ParamName == paramName && item.Number == number
select item).FirstOrDefault();
if (null == node)
{
LogHelper.Instance.GetCurrentClassError("没有找到这个节点信息");
}
return node;
}
public override OperateResult<T> GetValue<T>(string paramName, int stationId, int number = 1)
{
string msg = "";
OperateResult<T> result = new OperateResult<T>()
{
IsSuccess = false,
};
Variable node = (from storage in Storages
from item in storage.VariableList
where storage.StationId == stationId && item.ParamName == paramName && item.Number == number
select item).FirstOrDefault();
if (null == node || null == node.CurValue)
{
LogHelper.Instance.Error($"没有节点信息:{paramName},工站:{stationId},number:{number}");
msg = $"获取内存PLC数据失败addr:{node.Address}{node.VarName}number:{number},{stationId}";
result.Message = msg;
return result;
}
else
{
result.Content = (T)Convert.ChangeType(node.CurValue, typeof(T));
result.IsSuccess = true;
return result;
}
}
//可以发送多个地址
public override OperateResult Writes(string[] tags, object[] values, int maxCount = Global.MAX_READS)
{
OperateResult result = new OperateResult()
{
IsSuccess = false
};
try
{
for (int i = 0; i < maxCount; i++)
{
result.IsSuccess = opcUaClient.WriteNodes(tags, values); //现在不能写,因为
if (result.IsSuccess)
{
break;
}
Thread.Sleep(100);
}
//写不成功就断开链接暂时屏蔽针对OPC UA因为重建session需要成本太大
//230605
//IsConnect = false;
//出异常再捕获,写不成功暂时不捕获
//LogHelper.Instance.Info($"写数据失败,节点 = {tags.ToString()},值={values.ToString()}");
}
catch (Exception ex)
{
LogHelper.Instance.Error($"写数据失败,节点 = {tags},值={values},失败原因:{ex}");
_unityContainer.Resolve<LogService>().AddLog($"PLC_OpcUaClient:写数据失败,节点 = {tags},值={values}", E_LogType.Error.ToString());
}
return result;
}
//T:可以为数组
public override OperateResult Write<T>(string address, T data, int maxCount = Global.MAX_READS)
{
OperateResult result = new OperateResult()
{
IsSuccess = false
};
try
{
for (int i = 0; i < maxCount; i++)
{
if (!opcUaClient.Connected)
{
return result;
}
result.IsSuccess = opcUaClient.WriteNode<T>(address, data); //现在不能写,因为
if (result.IsSuccess)
{
break;
//return result;
}
Thread.Sleep(199);
}
//230605
//IsConnect = false;
//LogHelper.Instance.Info($"写数据失败,节点 = {address},值={data.ToString()}");
}
catch (Exception ex)
{
LogHelper.Instance.Error($"写数据失败,节点 = {address},值={data},失败原因:{ex}");
_unityContainer.Resolve<LogService>().AddLog($"PLC_OpcUaClient:Write:写数据失败,节点 = {address},值={data},失败原因:" + ex.Message, E_LogType.Error.ToString());
}
return result;
}
/// <summary>
/// 订阅节点//AddSubscription单线程回调模型。因此只要你的回调方法没有主动开线程就是串行执行。
/// </summary>
private void SubscribeNodes()
{
string nodeAddr = "";
List<Variable> SubInfoNodes = (from v in VariableList
orderby v.Index
where v.TrigEnable == true //按读的数据类型分组 炉子有42个信号
select v).ToList();
try
{
foreach (var node in SubInfoNodes)
{
nodeAddr = $"{node.Address}{node.VarName}";
opcUaClient.RemoveSubscription(node.Id.ToString());
opcUaClient.AddSubscription(node.Id.ToString(), nodeAddr, SubCallback); //NotificationReceived 事件处理器,当数据变化时,这个处理器会被异步调用
}
}
catch (Exception ex)
{
LogHelper.Instance.Fatal($"订阅时报错,{nodeAddr},{ConnectString},{ex.Message}.");
_unityContainer.Resolve<LogService>().AddLog($"PLC_OpcUaClient:订阅时报错,{nodeAddr},{ConnectString},{ex.Message}.", E_LogType.Debug.ToString());
}
}
/// <summary>
/// 执行订阅的事件(方法)
/// </summary>
/// <param name="key">node.TrigJson</param>
/// <param name="monitoredItem">节点的值</param>
/// <param name="args"></param>
private void SubCallback(string key, MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs args)
{
int Id = 0;
try
{
lock (_objLock)
{
Id = int.Parse(key);
if (0 == Id) //OPC服务退出会触发这里
{
LogHelper.Instance.Fatal("OPC触发异常!");
return;
}
// 如果有多个的订阅值都关联了当前的方法可以通过key和monitoredItem来区分
MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;
Variable node = VariableDic[Id]; //索引,之前是遍历
if (null == notification || null == notification.Value
|| null == notification.Value.WrappedValue.Value) //key
{
LogHelper.Instance.Fatal($"触发节点编号;{node.Id},{node.VarDesc},读取数据失败!");
return;
}
if (null == node)
{
LogHelper.Instance.GetCurrentClassWarn("必须对应唯一的一个Write节点");
return;
}
//foreach (var value in monitoredItem.DequeueValues())
//{
//}
//LogHelper.Instance.Info($"1-----SubCallback---回调:{Id}-----{monitoredItem.StartNodeId.ToString()}------信号,线程ID:{System.Threading.Thread.CurrentThread.ManagedThreadId}"); //此为多线程
_unityContainer.Resolve<PLCBlockingCollection>().MsgBlock.Add(new BlockData(notification.Value, node));
//_trigService.RecvTrigInfo(notification.Value, node);
}
}
catch (Exception e)
{
LogHelper.Instance.Info($"OPC 触发解析出错,{key}{e.Message}");
_unityContainer.Resolve<LogService>().AddLog($"PLC_OpcUaClient:OPC 触发解析出错,{key}{e.Message}", E_LogType.Debug.ToString());
}
}
}
}

View File

@@ -0,0 +1,55 @@
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("Cowain.Bake.Communication")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Cowain.Bake.Communication")]
[assembly: AssemblyCopyright("Copyright © 2023")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
//将 ComVisible 设置为 false 将使此程序集中的类型
//对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
//若要开始生成可本地化的应用程序,请设置
//.csproj 文件中的 <UICulture>CultureYouAreCodingWith</UICulture>
//例如,如果您在源文件中使用的是美国英语,
//使用的是美国英语,请将 <UICulture> 设置为 en-US。 然后取消
//对以下 NeutralResourceLanguage 特性的注释。 更新
//以下行中的“en-US”以匹配项目文件中的 UICulture 设置。
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[assembly:ThemeInfo(
ResourceDictionaryLocation.None, //主题特定资源词典所处位置
//(未在页面中找到资源时使用,
//或应用程序资源字典中找到时使用)
ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置
//(未在页面中找到资源时使用,
//、应用程序或任何主题专用资源字典中找到时使用)
)]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,62 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本: 4.0.30319.42000
//
// 对此文件的更改可能导致不正确的行为,如果
// 重新生成代码,则所做更改将丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace Cowain.Bake.Communication.Properties {
/// <summary>
/// 强类型资源类,用于查找本地化字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或删除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// 返回此类使用的缓存 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if ((resourceMan == null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Cowain.Bake.Communication.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 重写当前线程的 CurrentUICulture 属性,对
/// 使用此强类型资源类的所有资源查找执行重写。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Cowain.Bake.Communication.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}

View File

@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@@ -0,0 +1,177 @@
using Cognex.DataMan.SDK;
using Cognex.DataMan.SDK.Utils;
using Cowain.Bake.Common;
using Cowain.Bake.Common.Core;
using Cowain.Bake.Communication.Interface;
using HslCommunication;
using Newtonsoft.Json;
using Prism.Services.Dialogs;
using System;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using Unity;
namespace Cowain.Bake.Communication.Scan
{
public class Cognex : IScanCodeBase
{
IUnityContainer _unityContainer;
private bool? isConnect = null;
private DataManSystem _system = null;
string DecodeStr = "";
ManualResetEvent resetEvent = new ManualResetEvent(false);
public override bool IsConnect
{
get
{
return isConnect??false;
}
set
{
isConnect = value;
}
}
public Cognex(IUnityContainer unityContainer, IDialogService dialogService) : base(unityContainer, dialogService)
{
_unityContainer = unityContainer;
}
private void MySystem_ImageArrived(object sender, ImageArrivedEventArgs args)
{
}
private void MySystem_ReadStringArrived(object sender, ReadStringArrivedEventArgs args)
{
//AcqCount += 1;
DecodeStr = args.ReadString;
resetEvent.Set(); // 发送信号,通知主线程接收到数据
//OutputLog("收到结果");
}
string ExecCommand(string cmd)
{
if (!IsConnect)
{
return "";
}
DecodeStr = "";
LogHelper.Instance.Info($"开始扫码:{Name}");
resetEvent.Reset();
_system?.SendCommand(cmd);
// 等待扫码枪回调返回数据
resetEvent.WaitOne(3000); // 阻塞等待,直到回调触发 .WaitOne(timeoutMs);
//_system.SendCommand("TRIGGER OFF");// 无论是否成功,都停止触发
LogHelper.Instance.Info($"结束扫码:{Name},{DecodeStr}");
return DecodeStr;
}
private void MySystem_SystemDisconnected(object sender, System.EventArgs args)
{
isConnect = false;
resetEvent.Set(); // 发送信号,通知主线程接收到数据
//OutputLog("断开连接");
}
private void MySystem_SystemConnected(object sender, System.EventArgs args)
{
isConnect = true;
}
private void MySystem_ImageGraphicsArrived(object sender, ImageGraphicsArrivedEventArgs args)
{
}
public void RegisterSystemEvent()
{
_system.SystemConnected += MySystem_SystemConnected;
_system.SystemDisconnected += MySystem_SystemDisconnected;
_system.ReadStringArrived += MySystem_ReadStringArrived;
_system.ImageArrived += MySystem_ImageArrived;
_system.ImageGraphicsArrived += MySystem_ImageGraphicsArrived;
}
public override bool Connect()
{
if (IsConnect)
{
_system?.Disconnect();
}
EthSystemConnector conn = new EthSystemConnector(IPAddress.Parse(Ip), Port);
conn.UserName = "admin";
conn.Password = "";
_system = new DataManSystem(conn);
_system.DefaultTimeout = 500;
//注册事件
RegisterSystemEvent();
_system.SetResultTypes(ResultTypes.ReadString);
_system.Connect();
// 设置扫码枪模式(同步)
if (_system.Connector.State != ConnectionState.Connected)
{
return false;
}
return true;
}
public override OperateResult<string> ReadCode()
{
string barcode = "";
OperateResult<string> result = new OperateResult<string>()
{
IsSuccess = false,
};
for (int i = 0; i < Global.SCANCODE_COUNT; i++)
{
barcode = ExecCommand(Command);
if (!string.IsNullOrEmpty(FilterRegex))
{
barcode = Regex.Replace(barcode, FilterRegex, "");
}
if (!barcode.Contains("ERROR")
&& !string.IsNullOrEmpty(barcode))
{
result.Content = barcode;
result.IsSuccess = true;
break;
}
else
{
//ExecCommand(CloseCommand);
_system?.SendCommand(CloseCommand);
}
}
return result;
}
public override void Close()
{
_system?.Disconnect();
}
public override void GetJsonParam(string param)
{
try
{
dynamic d = JsonConvert.DeserializeObject<dynamic>(param);
Ip = d.Ip;
Port = d.Port;
Command = d.Command;
FilterRegex = d.FilterCodes; //去掉返回不要的码
CloseCommand = d.CloseCommand;
if (string.IsNullOrEmpty(Ip)
|| string.IsNullOrEmpty(Command))
{
LogHelper.Instance.GetCurrentClassError("扫码枪解析出错:" + param);
}
}
catch (Exception ex)
{
LogHelper.Instance.GetCurrentClassError($"扫码枪解析出错:{param},{ex}");
}
}
}
}

View File

@@ -0,0 +1,133 @@
using Cowain.Bake.Common;
using Cowain.Bake.Common.Core;
using Cowain.Bake.Communication.Interface;
using Cowain.Bake.Communication.Models;
using Cowain.Bake.Communication.Sokects;
using HslCommunication;
using Newtonsoft.Json;
using Prism.Services.Dialogs;
using System;
using System.Threading;
using Unity;
namespace Cowain.Bake.Communication.Scan
{
public class Honeywell : IScanCodeBase
{
string DataPack = "";
TcpSocketClient tcpClient = null;
IUnityContainer _unityContainer;
MessageEventWaitHandle<string> messageEvent { get; set; }
public Honeywell(IUnityContainer unityContainer, IDialogService dialogService) : base(unityContainer, dialogService)
{
_unityContainer = unityContainer;
messageEvent = new MessageEventWaitHandle<string>(false, EventResetMode.ManualReset);
}
public override bool Connect()
{
tcpClient = new TcpSocketClient(Ip, Port);
tcpClient.ValueChanged += (sender, e) =>
{
IsConnect = ((TcpSocketClient)sender).IsConnected;
SetStatus(Id, IsConnect);
};
tcpClient.ReceivedString += TcpClient_ReceivedString; ;
tcpClient.ConnectServer();
return true;
}
public override void GetJsonParam(string param)
{
try
{
dynamic d = JsonConvert.DeserializeObject<dynamic>(param);
Ip = d.Ip;
Port = d.Port;
Command = d.Command;
FilterRegex = d.FilterCodes; //去掉返回不要的码
CloseCommand = d.CloseCommand;
if (string.IsNullOrEmpty(Ip)
|| string.IsNullOrEmpty(Command))
{
LogHelper.Instance.GetCurrentClassError("扫码枪解析出错:" + param);
}
}
catch (Exception ex)
{
LogHelper.Instance.GetCurrentClassError($"扫码枪解析出错:{param},{ex} ");
}
}
private void TcpClient_ReceivedString(string obj)
{
messageEvent.Set(obj);
}
public override void Close()
{
tcpClient.ConnectClose();
}
private bool isConnect;
public override bool IsConnect
{
get
{
isConnect = tcpClient.IsConnected;
return isConnect;
}
set
{
isConnect = value;
}
}
public override OperateResult<string> ReadCode()
{
OperateResult plcResult;
ExOperateResult<string> result = new ExOperateResult<string>()
{
IsSuccess = false
};
for (int i = 0; i < Global.MAX_READS; i++)
{
var array = Command.Split('+');
var command = array[0];
if (array.Length > 1 && array[1] == "NewLine")
{
plcResult = tcpClient.SendString(command + Environment.NewLine);
}
else
{
plcResult = tcpClient.SendString(command);
}
result.IsSuccess = plcResult.IsSuccess;
result.Message = plcResult.Message;
result.ErrorCode = plcResult.ErrorCode;
if (!result.IsSuccess)
{
result.Message = "发送数据失";
LogHelper.Instance.Error($"发送数据失败,发送数据:{Command}");
continue;
}
DataPack = messageEvent.GetMessage(1 * Global.SECONDS_TO_MILLISCONDS);//"0\r\n"
if (string.IsNullOrEmpty(DataPack)) //超时才返回为空
{
result.Message = "失败";
result.IsSuccess = false;
result.Content = "操作超时!";
}
result.Content = DataPack?.Replace("\r\n","");
break;
}
return result;
}
}
}

View File

@@ -0,0 +1,167 @@
using Cowain.Bake.Common;
using Cowain.Bake.Common.Core;
using Cowain.Bake.Communication.Interface;
using Cowain.Bake.Communication.Models;
using HslCommunication;
using Keyence.AutoID.SDK;
using Newtonsoft.Json;
using Prism.Services.Dialogs;
using System;
using System.Text.RegularExpressions;
using Unity;
namespace Cowain.Bake.Communication.Scan
{
public class Keyence : IScanCodeBase
{
IUnityContainer _unityContainer;
public Keyence(IUnityContainer unityContainer, IDialogService dialogService) : base(unityContainer, dialogService)
{
_unityContainer = unityContainer;
}
public override void GetJsonParam(string param)
{
try
{
dynamic d = JsonConvert.DeserializeObject<dynamic>(param);
Ip = d.Ip;
Port = d.Port;
Command = d.Command;
FilterRegex = d.FilterCodes; //去掉返回不要的码
CloseCommand = d.CloseCommand;
if (string.IsNullOrEmpty(Ip)
|| string.IsNullOrEmpty(Command))
{
LogHelper.Instance.GetCurrentClassError("扫码枪解析出错:" + param);
}
}
catch (Exception ex)
{
LogHelper.Instance.GetCurrentClassError($"扫码枪解析出错:{param},{ex}");
}
}
private bool? isConnect = null;
//private bool? lastConnect = null;
//public event EventHandler<ValueChangedEventArgs> ValueChanged;
public override bool IsConnect
{
get
{
bool connectStatus = false;
if (null == reader)
{
isConnect = false;
}
else
{
string vervion =reader.ExecCommand("KEYENCE"); //OK,KEYENCE,SR-1000,1.42,4.604
if (vervion.Contains("OK"))
{
connectStatus = true;
}
else
{
LogHelper.Instance.GetCurrentClassError($"扫码枪连接失败,{this.Name},错误码:{reader.LastErrorInfo},返回版本:{vervion}");
}
//(int)reader.LastErrorInfo=0拔网络是0//((0 == (int)reader.LastErrorInfo || 5 == (int)reader.LastErrorInfo) ? true : false);
if (connectStatus != isConnect)
{
isConnect = connectStatus;
SetStatus(Id, connectStatus);
}
}
return connectStatus;
}
set
{
isConnect = value;
SetStatus(Id, value);
}
}
//protected virtual void OnValueChanged(bool newValue)
//{
// SetStatus(Id, lastConnect.Value);
// //ValueChanged?.Invoke(this, new ValueChangedEventArgs { NewValue = newValue });
//}
/// <summary>
/// 基恩士扫码枪的读取器
/// </summary>
private ReaderAccessor reader { set; get; }
public override bool Connect()
{
Close();
reader = new ReaderAccessor(Ip);
reader.CommandPort = Port;
reader.DataPort = Port;
IsConnect = reader.Connect();
return IsConnect;
}
public override OperateResult<string> ReadCode()
{
string barcode = "";
ExOperateResult<string> result = new ExOperateResult<string>()
{
IsSuccess = false,
};
for (int i = 0; i < Global.SCANCODE_COUNT; i++)
{
barcode = reader.ExecCommand(Command, Global.MAX_TCP_READ_OUTTIME);
if (!string.IsNullOrEmpty(FilterRegex))
{
barcode = Regex.Replace(barcode, FilterRegex, "");
}
if (!barcode.Contains("ERROR")
&& !barcode.Contains("KEYENCE")
&& !string.IsNullOrEmpty(barcode))
{
result.Content = barcode;
result.IsSuccess = true;
break;
}
else
{
reader.ExecCommand(CloseCommand);
}
}
return result;
}
public override void Close()
{
try
{
if (reader != null)
{
reader.Disconnect();
reader.Dispose();
reader = null;
}
}
catch (Exception ex)
{
LogHelper.Instance.GetCurrentClassError("扫码枪关闭失败:" + ex.Message);
}
finally
{
reader = null;
}
}
~Keyence()
{
Close();
}
}
}

View File

@@ -0,0 +1,69 @@
using Cowain.Bake.BLL;
using Cowain.Bake.Common;
using Cowain.Bake.Common.Core;
using Cowain.Bake.Common.Enums;
using Cowain.Bake.Communication.Interface;
using Cowain.Bake.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Unity;
namespace Cowain.Bake.Communication.Scan
{
public class ScanCodeManage
{
private List<TDeviceConfig> scanCodeList;
IUnityContainer _unityContainer;
public ScanCodeManage(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
scanCodeList = unityContainer.Resolve<DeviceConfigService>().GetConfig(EDeviceType.SCANNER);
List<Task> listTask = new List<Task>();
foreach (var item in scanCodeList)
{
Assembly asm = Assembly.GetExecutingAssembly(); //获得当前程序的绝对路径
Type type = asm.GetType(MyPath.SCAN + item.DriverName);
unityContainer.RegisterSingleton(typeof(IScanCodeBase), type, item.Name);
var scanCode = _unityContainer.Resolve<IScanCodeBase>(item.Name); //几个PLC就实例化几个
scanCode.Id = item.Id;
scanCode.Name = item.Name;
scanCode.DeviceName = item.DriverName;
scanCode.GetJsonParam(item.Json);
if (item.Enable)
{
listTask.Add(Task.Run(() =>
{
scanCode.Connect();
}));
}
}
Task.WaitAll(listTask.ToArray());
Task.Run(async () =>
{
while(true)
{
await Task.Delay(5000);
CheckConnect();
}
});
}
void CheckConnect()
{
var scanCodes = _unityContainer.ResolveAll<IScanCodeBase>();
foreach(var item in scanCodes)
{
bool b = item.IsConnect;
}
}
}
}

View File

@@ -0,0 +1,98 @@
using FluentFTP;
namespace Cowain.Bake.Communication.Sokects
{
//全部都是远程操作
public class FtpHelper
{
#region
public string IpAddr { get; set; } /// IP地址
public string RelatePath { get; set; } /// 相对路径
public int Port { get; set; } /// 端口号
public string UserName { get; set; } /// 用户名
public string Password { get; set; } /// 密码
//https://blog.csdn.net/fengershishe/article/details/129140618
public FtpHelper()
{
}
public FtpHelper(string ipAddr, int port, string userName, string password, string relatePath = "")
{
this.IpAddr = ipAddr;
this.Port = port;
this.UserName = userName;
this.Password = password;
this.RelatePath = relatePath;
}
#endregion
#region
public FtpListItem[] ListDir()
{
FtpListItem[] lists;
using (var ftpClient = new FtpClient(this.IpAddr, this.UserName, this.Password, this.Port))
{
ftpClient.Connect(); // 连接到FTP服务器
ftpClient.SetWorkingDirectory(this.RelatePath);
lists = ftpClient.GetListing();
}
return lists;
}
// 上传文件
public bool UpLoad(string src, string desc)
{
using (var ftpClient = new FtpClient(this.IpAddr, this.UserName, this.Password, this.Port))
{
ftpClient.Connect();
FtpStatus result = ftpClient.UploadFile(src, desc); // ("local/file.txt", "remote/file.txt");
ftpClient.Disconnect();
return FtpStatus.Success == result ? true : false;
}
}
///创建目录(远程创建)
private bool CheckDirIsExists(string dir)
{
bool flag = false;
using (var ftpClient = new FtpClient(this.IpAddr, this.UserName, this.Password, this.Port))
{
ftpClient.Connect();
ftpClient.SetWorkingDirectory(this.RelatePath);
flag = ftpClient.DirectoryExists(dir);
if (!flag)
{
flag = ftpClient.CreateDirectory(dir); //client.CreateDirectory("remote/directory");
}
}
return flag;
}
public void DeleteFile(string dir)
{
using (var ftpClient = new FtpClient(this.IpAddr, this.UserName, this.Password, this.Port))
{
ftpClient.Connect();
ftpClient.SetWorkingDirectory(this.RelatePath);
ftpClient.DeleteFile(dir);
ftpClient.Disconnect();
}
}
public bool DownloadFile(string localAddress, string remoteAddress)
{
using (var ftpClient = new FtpClient(this.IpAddr, this.UserName, this.Password, this.Port))
{
ftpClient.SetWorkingDirectory(this.RelatePath);
ftpClient.Connect();
if (ftpClient.DownloadFile(localAddress, remoteAddress) == FtpStatus.Success)
{
return true;
}
}
return false;
}
#endregion
}
}

View File

@@ -0,0 +1,47 @@
using Cowain.Bake.Common.Interface;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Unity;
namespace Cowain.Bake.Communication.Sokects
{
public class HttpServer
{
IRecvMesHttp MesServer { get; set; }
IUnityContainer _unityContainer;
public HttpServer(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
public void Start()
{
using (HttpListener listener = new HttpListener())
{
listener.Prefixes.Add("http://localhost:8089/");
listener.Start();
while (true)
{
HttpListenerContext context = listener.GetContext();
HttpListenerRequest request = context.Request;
HttpListenerResponse response = context.Response;
//string url = request.Url.AbsolutePath;
string replyData = MesServer.RecvInfo(request);
byte[] buffer = Encoding.UTF8.GetBytes(replyData);
response.ContentLength64 = buffer.Length;
Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
output.Close();
response.Close();
}
}
}
}
}

View File

@@ -0,0 +1,230 @@
using Cowain.Bake.Common.Core;
using HslCommunication;
using HslCommunication.Core.Net;
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace Cowain.Bake.Communication.Sokects
{
public class TcpSocketClient : NetworkXBase
{
private Encoding encoding;
private object connectLock = new object();
public string Ip { get; set; } = "127.0.0.1";
public int Port { get; set; } = 10000;
// 声明一个事件,通知变量变化
// 定义委托
public delegate void ValueChangedEventHandler(object sender, EventArgs e);
// 声明事件
public event ValueChangedEventHandler ValueChanged;
private bool _isConnected;
public bool IsConnected
{
get { return _isConnected; }
set
{
_isConnected = value;
OnValueChanged();
}
} //CoreSocket.Connected
private int bufferLength = 2048;
private byte[] buffer = null;
// 触发事件的方法
public virtual void OnValueChanged()
{
ValueChanged?.Invoke(this, EventArgs.Empty);
}
/// <summary>
/// 当前的编码器
/// </summary>
public Encoding Encoding
{
get
{
return encoding;
}
set
{
encoding = value;
}
}
/// <summary>
/// 当接收到字符串时候的触发事件
/// </summary>
public event Action<string> ReceivedString;
/// <summary>
/// 实例化一个默认的对象
/// </summary>
//public TcpSocketClient()
//{
// buffer = new byte[bufferLength];
// encoding = Encoding.UTF8;
//}
/// <summary>
/// 使用指定的ip地址和端口号来实例化这个对象
/// </summary>
/// <param name="ipAddress">Ip地址</param>
/// <param name="port">端口号</param>
public TcpSocketClient(string ipAddress, int port)
{
buffer = new byte[bufferLength];
encoding = Encoding.UTF8;
this.Ip = ipAddress;
this.Port = port;
}
/// <summary>
/// 连接服务器
/// </summary>
/// <returns>返回是否连接成功</returns>
public OperateResult ConnectServer()
{
CoreSocket?.Close();
OperateResult<Socket> operateResult = CreateSocketAndConnect(Ip, Port, 5000);
IsConnected = operateResult.IsSuccess;
if (!operateResult.IsSuccess)
{
return operateResult;
}
try
{
CoreSocket = operateResult.Content;
CoreSocket.BeginReceive(buffer, 0, bufferLength, SocketFlags.None, ReceiveCallBack, CoreSocket);
return OperateResult.CreateSuccessResult();
}
catch (Exception ex)
{
LogHelper.Instance.Error("连接MOM系统失败", true);
return new OperateResult(ex.Message);
}
}
/// <summary>
/// 关闭当前的连接对象
/// </summary>
/// <returns>错误信息</returns>
public OperateResult ConnectClose()
{
try
{
CoreSocket?.Close();
return OperateResult.CreateSuccessResult();
}
catch (Exception ex)
{
return new OperateResult(ex.Message);
}
}
/// <summary>
/// 发送字符串到网络上去
/// </summary>
/// <param name="text">文本信息</param>
/// <returns>发送是否成功</returns>
public OperateResult SendString(string text)
{
if (string.IsNullOrEmpty(text))
{
return OperateResult.CreateSuccessResult();
}
return Send(CoreSocket, encoding.GetBytes(text));
}
public OperateResult Send(byte[] text)
{
return Send(CoreSocket, text);
}
private void ReceiveCallBack(IAsyncResult ar)
{
Socket socket = ar.AsyncState as Socket;
if (socket == null)
{
return;
}
byte[] array = null;
try
{
int num = socket.EndReceive(ar);
socket.BeginReceive(buffer, 0, bufferLength, SocketFlags.None, ReceiveCallBack, socket);
if (num == 0)
{
IsConnected = false;
CoreSocket?.Close();
return;
}
array = new byte[num];
Array.Copy(buffer, 0, array, 0, num);
}
catch (ObjectDisposedException)
{
}
catch (Exception ex2)
{
base.LogNet?.WriteWarn(StringResources.Language.SocketContentReceiveException + ":" + ex2.Message);
ThreadPool.QueueUserWorkItem(ReConnectServer, null);
}
if (array != null)
{
this.ReceivedString?.Invoke(encoding.GetString(array));
}
}
/// <summary>
/// 是否是处于重连的状态
/// </summary>
/// <param name="obj">无用的对象</param>
public void ReConnectServer(object obj)
{
base.LogNet?.WriteWarn(StringResources.Language.ReConnectServerAfterTenSeconds);
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
base.LogNet?.WriteWarn($"Wait for connecting server after {9 - i} seconds");
}
OperateResult<Socket> operateResult = CreateSocketAndConnect(Ip, Port, 5000);
IsConnected = operateResult.IsSuccess;
if (!operateResult.IsSuccess)
{
//用于将工作项添加到线程池的方法。它允许你将一个委托Delegate或方法作为参数添加到线程池中以便由线程池中的线程执行
//ThreadPool.QueueUserWorkItem(ReConnectServer, obj); //加上它只要一次重连就可以了不加他就可以执行多次。add by lsm
return;
}
lock (connectLock)
{
try
{
CoreSocket?.Close();
CoreSocket = operateResult.Content;
CoreSocket.BeginReceive(buffer, 0, bufferLength, SocketFlags.None, ReceiveCallBack, CoreSocket);
base.LogNet?.WriteWarn(StringResources.Language.ReConnectServerSuccess);
}
catch (Exception ex)
{
base.LogNet?.WriteWarn(StringResources.Language.RemoteClosedConnection + ":" + ex.Message);
ThreadPool.QueueUserWorkItem(ReConnectServer, obj);
}
}
}
/// <summary>
/// 返回表示当前对象的字符串
/// </summary>
/// <returns>字符串</returns>
public override string ToString()
{
return $"NetPlainSocket[{Ip}:{Port}]";
}
}
}

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.2.1.0" newVersion="1.2.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.CodeAnalysis" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.CodeAnalysis.CSharp" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="BouncyCastle.Crypto" publicKeyToken="0e99375e54769942" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.8.5.0" newVersion="1.8.5.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.4.0" newVersion="4.1.4.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Encoding.CodePages" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.6" newVersion="9.0.0.6" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]

View File

@@ -0,0 +1,206 @@
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.Communication.dll.config
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.Communication.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.Communication.pdb
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Cognex.DataMan.SDK.Discovery.PC.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Cognex.DataMan.SDK.PC.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Cognex.DataMan.SDK.Utils.PC.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Communication.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.BLL.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.Common.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.Model.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\FluentFTP.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\HandyControl.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\HslCommunication.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Keyence.AutoID.SDK.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.Bcl.AsyncInterfaces.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.Bcl.HashCode.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.CodeAnalysis.CSharp.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.CodeAnalysis.CSharp.Scripting.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.CodeAnalysis.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.CodeAnalysis.Scripting.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.Extensions.Logging.Abstractions.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.Xaml.Behaviors.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Newtonsoft.Json.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Opc.Ua.Bindings.Https.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Opc.Ua.Client.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Opc.Ua.ClientControls.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Opc.Ua.Configuration.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Opc.Ua.Core.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Opc.Ua.Security.Certificates.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Opc.Ua.Server.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\OpcUaHelper.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Prism.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Prism.Unity.Wpf.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Prism.Wpf.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\System.Buffers.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\System.Memory.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\System.Numerics.Vectors.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\System.Runtime.CompilerServices.Unsafe.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\System.Text.Encoding.CodePages.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\System.Text.Encodings.Web.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\System.Text.Json.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\System.Threading.Tasks.Extensions.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\System.ValueTuple.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Unity.Abstractions.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Unity.Container.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\MySql.Data.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\EntityFramework.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\CsvHelper.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\NLog.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.AspNetCore.Http.Abstractions.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.AspNetCore.Hosting.Abstractions.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.AspNetCore.Hosting.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.AspNetCore.Http.Features.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\System.ServiceModel.Primitives.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\System.Formats.Asn1.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\BouncyCastle.Crypto.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Google.Protobuf.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\ZstdNet.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\K4os.Compression.LZ4.Streams.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Ubiety.Dns.Core.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.AspNetCore.Hosting.Server.Abstractions.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.AspNetCore.Http.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\K4os.Compression.LZ4.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\K4os.Hash.xxHash.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.BLL.pdb
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.BLL.dll.config
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.Common.pdb
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.Common.dll.config
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.Model.pdb
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.Model.dll.config
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\FluentFTP.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\HandyControl.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.Bcl.AsyncInterfaces.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.CodeAnalysis.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.CodeAnalysis.CSharp.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.CodeAnalysis.CSharp.Scripting.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.CodeAnalysis.Scripting.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.Xaml.Behaviors.pdb
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Microsoft.Xaml.Behaviors.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Newtonsoft.Json.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\System.Buffers.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\System.Memory.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\System.Numerics.Vectors.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\System.Runtime.CompilerServices.Unsafe.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\System.Text.Encoding.CodePages.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\System.Text.Encodings.Web.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\System.Text.Json.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\System.Threading.Tasks.Extensions.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\System.ValueTuple.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Unity.Abstractions.pdb
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Unity.Container.pdb
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Google.Protobuf.pdb
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\Google.Protobuf.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\K4os.Compression.LZ4.Streams.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\K4os.Compression.LZ4.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\bin\Debug\K4os.Hash.xxHash.xml
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\obj\Debug\Cowain.Bake.Communication.csproj.AssemblyReference.cache
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\obj\Debug\Cowain.Bake.Communication.Properties.Resources.resources
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\obj\Debug\Cowain.Bake.Communication.csproj.GenerateResource.cache
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\obj\Debug\Cowain.Bake.Communication.csproj.CoreCompileInputs.cache
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\obj\Debug\Cowain.Bake.Communication.csproj.CopyComplete
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\obj\Debug\Cowain.Bake.Communication.dll
E:\svn\DryingStove\branch\得壹烘烤线6098-006\src1111\src\Cowain.Bake.Communication\obj\Debug\Cowain.Bake.Communication.pdb
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.Communication.dll.config
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.Communication.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.Communication.pdb
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Cognex.DataMan.SDK.Discovery.PC.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Cognex.DataMan.SDK.PC.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Cognex.DataMan.SDK.Utils.PC.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Communication.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.BLL.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.Common.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.Model.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\FluentFTP.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\HandyControl.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\HslCommunication.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Keyence.AutoID.SDK.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.Bcl.AsyncInterfaces.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.Bcl.HashCode.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.CodeAnalysis.CSharp.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.CodeAnalysis.CSharp.Scripting.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.CodeAnalysis.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.CodeAnalysis.Scripting.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.Extensions.Logging.Abstractions.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.Xaml.Behaviors.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Newtonsoft.Json.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Opc.Ua.Bindings.Https.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Opc.Ua.Client.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Opc.Ua.ClientControls.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Opc.Ua.Configuration.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Opc.Ua.Core.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Opc.Ua.Security.Certificates.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Opc.Ua.Server.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\OpcUaHelper.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Prism.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Prism.Unity.Wpf.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Prism.Wpf.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\System.Buffers.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\System.Memory.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\System.Numerics.Vectors.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\System.Runtime.CompilerServices.Unsafe.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\System.Text.Encoding.CodePages.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\System.Text.Encodings.Web.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\System.Text.Json.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\System.Threading.Tasks.Extensions.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\System.ValueTuple.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Unity.Abstractions.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Unity.Container.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\MySql.Data.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\EntityFramework.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\CsvHelper.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\NLog.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.AspNetCore.Http.Abstractions.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.AspNetCore.Hosting.Abstractions.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.AspNetCore.Hosting.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.AspNetCore.Http.Features.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\System.ServiceModel.Primitives.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\System.Formats.Asn1.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\BouncyCastle.Crypto.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Google.Protobuf.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\ZstdNet.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\K4os.Compression.LZ4.Streams.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Ubiety.Dns.Core.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.AspNetCore.Hosting.Server.Abstractions.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.AspNetCore.Http.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\K4os.Compression.LZ4.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\K4os.Hash.xxHash.dll
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.BLL.pdb
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.BLL.dll.config
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.Common.pdb
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.Common.dll.config
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.Model.pdb
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Cowain.Bake.Model.dll.config
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\FluentFTP.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\HandyControl.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.Bcl.AsyncInterfaces.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.CodeAnalysis.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.CodeAnalysis.CSharp.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.CodeAnalysis.CSharp.Scripting.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.CodeAnalysis.Scripting.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.Xaml.Behaviors.pdb
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Microsoft.Xaml.Behaviors.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Newtonsoft.Json.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\System.Buffers.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\System.Memory.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\System.Numerics.Vectors.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\System.Runtime.CompilerServices.Unsafe.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\System.Text.Encoding.CodePages.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\System.Text.Encodings.Web.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\System.Text.Json.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\System.Threading.Tasks.Extensions.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\System.ValueTuple.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Unity.Abstractions.pdb
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Unity.Container.pdb
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Google.Protobuf.pdb
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\Google.Protobuf.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\K4os.Compression.LZ4.Streams.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\K4os.Compression.LZ4.xml
D:\SourceCode\src\Cowain.Bake.Communication\bin\Debug\K4os.Hash.xxHash.xml
D:\SourceCode\src\Cowain.Bake.Communication\obj\Debug\Cowain.Bake.Communication.csprojAssemblyReference.cache
D:\SourceCode\src\Cowain.Bake.Communication\obj\Debug\Cowain.Bake.Communication.Properties.Resources.resources
D:\SourceCode\src\Cowain.Bake.Communication\obj\Debug\Cowain.Bake.Communication.csproj.GenerateResource.cache
D:\SourceCode\src\Cowain.Bake.Communication\obj\Debug\Cowain.Bake.Communication.csproj.CoreCompileInputs.cache
D:\SourceCode\src\Cowain.Bake.Communication\obj\Debug\Cowain.Bake.Communication.csproj.CopyComplete
D:\SourceCode\src\Cowain.Bake.Communication\obj\Debug\Cowain.Bake.Communication.dll
D:\SourceCode\src\Cowain.Bake.Communication\obj\Debug\Cowain.Bake.Communication.pdb

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CS-Script.bin" version="3.30.5.1" targetFramework="net472" />
<package id="FluentFTP" version="46.0.2" targetFramework="net472" />
<package id="HandyControl" version="3.5.1" targetFramework="net472" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="7.0.0" targetFramework="net472" />
<package id="Microsoft.CodeAnalysis.Analyzers" version="1.1.0" targetFramework="net472" />
<package id="Microsoft.CodeAnalysis.Common" version="2.0.0" targetFramework="net472" />
<package id="Microsoft.CodeAnalysis.CSharp" version="2.0.0" targetFramework="net472" />
<package id="Microsoft.CodeAnalysis.CSharp.Scripting" version="2.0.0" targetFramework="net472" />
<package id="Microsoft.CodeAnalysis.Scripting.Common" version="2.0.0" targetFramework="net472" />
<package id="Microsoft.Xaml.Behaviors.Wpf" version="1.1.31" targetFramework="net472" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net472" />
<package id="NLog" version="5.1.1" targetFramework="net472" />
<package id="Prism.Core" version="8.1.97" targetFramework="net472" />
<package id="Prism.Unity" version="8.1.97" targetFramework="net472" />
<package id="Prism.Wpf" version="8.1.97" targetFramework="net472" />
<package id="System.AppContext" version="4.3.0" targetFramework="net472" />
<package id="System.Buffers" version="4.5.1" targetFramework="net472" />
<package id="System.Collections" version="4.3.0" targetFramework="net472" />
<package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net472" />
<package id="System.Collections.Immutable" version="1.3.1" targetFramework="net472" />
<package id="System.Collections.Specialized" version="4.3.0" targetFramework="net472" />
<package id="System.Console" version="4.3.0" targetFramework="net472" />
<package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net472" />
<package id="System.Diagnostics.FileVersionInfo" version="4.3.0" targetFramework="net472" />
<package id="System.Diagnostics.StackTrace" version="4.3.0" targetFramework="net472" />
<package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="net472" />
<package id="System.Dynamic.Runtime" version="4.3.0" targetFramework="net472" />
<package id="System.Globalization" version="4.3.0" targetFramework="net472" />
<package id="System.IO" version="4.3.0" targetFramework="net472" />
<package id="System.IO.Compression" version="4.3.0" targetFramework="net472" />
<package id="System.IO.FileSystem" version="4.3.0" targetFramework="net472" />
<package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="net472" />
<package id="System.Linq" version="4.3.0" targetFramework="net472" />
<package id="System.Linq.Expressions" version="4.3.0" targetFramework="net472" />
<package id="System.Memory" version="4.5.5" targetFramework="net472" />
<package id="System.Net.NameResolution" version="4.3.0" targetFramework="net472" />
<package id="System.Net.Security" version="4.3.0" targetFramework="net472" />
<package id="System.Net.Sockets" version="4.3.0" targetFramework="net472" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
<package id="System.Reflection" version="4.3.0" targetFramework="net472" />
<package id="System.Reflection.Extensions" version="4.3.0" targetFramework="net472" />
<package id="System.Reflection.Metadata" version="1.4.2" targetFramework="net472" />
<package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="net472" />
<package id="System.Runtime" version="4.3.0" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net472" />
<package id="System.Runtime.Extensions" version="4.3.0" targetFramework="net472" />
<package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net472" />
<package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net472" />
<package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net472" />
<package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net472" />
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net472" />
<package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net472" />
<package id="System.Text.Encoding" version="4.3.0" targetFramework="net472" />
<package id="System.Text.Encoding.CodePages" version="9.0.6" targetFramework="net472" />
<package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net472" />
<package id="System.Text.Encodings.Web" version="7.0.0" targetFramework="net472" />
<package id="System.Text.Json" version="7.0.2" targetFramework="net472" />
<package id="System.Threading" version="4.3.0" targetFramework="net472" />
<package id="System.Threading.Tasks" version="4.3.0" targetFramework="net472" />
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net472" />
<package id="System.Threading.Tasks.Parallel" version="4.3.0" targetFramework="net472" />
<package id="System.Threading.Thread" version="4.3.0" targetFramework="net472" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net472" />
<package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net472" />
<package id="System.Xml.XDocument" version="4.3.0" targetFramework="net472" />
<package id="System.Xml.XmlDocument" version="4.3.0" targetFramework="net472" />
<package id="System.Xml.XPath" version="4.3.0" targetFramework="net472" />
<package id="System.Xml.XPath.XDocument" version="4.3.0" targetFramework="net472" />
<package id="Unity.Abstractions" version="5.11.7" targetFramework="net472" />
<package id="Unity.Container" version="5.11.11" targetFramework="net472" />
</packages>