Commit 88824370 张东亮

init

0 个父辈
正在显示 97 个修改的文件 包含 15180 行增加0 行删除
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
project.fragment.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
#*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
\ No newline at end of file \ No newline at end of file

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30104.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AGV_3D_Line", "AGV_3D_Line\AGV_3D_Line.csproj", "{E1C3207D-C67D-4B46-A9DB-D182F2074CCB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AgvClient", "AgvClient\AgvClient.csproj", "{D9154766-67B0-4082-AF8B-DCC7C4CFB5A2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AgvClientTest", "AgvClientTest\AgvClientTest.csproj", "{E1C0827A-FA12-49A9-AC71-6D3E6518754A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebServiceHost", "WebServiceTest\WebServiceHost.csproj", "{A89F6EC4-457A-4998-ACDC-F1ADC22C8BF8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E1C3207D-C67D-4B46-A9DB-D182F2074CCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E1C3207D-C67D-4B46-A9DB-D182F2074CCB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E1C3207D-C67D-4B46-A9DB-D182F2074CCB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E1C3207D-C67D-4B46-A9DB-D182F2074CCB}.Release|Any CPU.Build.0 = Release|Any CPU
{D9154766-67B0-4082-AF8B-DCC7C4CFB5A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D9154766-67B0-4082-AF8B-DCC7C4CFB5A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D9154766-67B0-4082-AF8B-DCC7C4CFB5A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D9154766-67B0-4082-AF8B-DCC7C4CFB5A2}.Release|Any CPU.Build.0 = Release|Any CPU
{E1C0827A-FA12-49A9-AC71-6D3E6518754A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E1C0827A-FA12-49A9-AC71-6D3E6518754A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E1C0827A-FA12-49A9-AC71-6D3E6518754A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E1C0827A-FA12-49A9-AC71-6D3E6518754A}.Release|Any CPU.Build.0 = Release|Any CPU
{A89F6EC4-457A-4998-ACDC-F1ADC22C8BF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A89F6EC4-457A-4998-ACDC-F1ADC22C8BF8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A89F6EC4-457A-4998-ACDC-F1ADC22C8BF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A89F6EC4-457A-4998-ACDC-F1ADC22C8BF8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6958A655-C82F-4C09-951F-24E629575E89}
EndGlobalSection
EndGlobal
<?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>{E1C3207D-C67D-4B46-A9DB-D182F2074CCB}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>AGV_3D_Line</RootNamespace>
<AssemblyName>AGV_3D_Line</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<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' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>line.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="AsaPL.AgvClient">
<HintPath>..\AgvClient\bin\Debug\AsaPL.AgvClient.dll</HintPath>
</Reference>
<Reference Include="log4net">
<HintPath>dll\log4net.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=3.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>dll\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="RestSharp, Version=106.11.4.0, Culture=neutral, PublicKeyToken=598062e77f915f75, processorArchitecture=MSIL">
<HintPath>..\packages\RestSharp.106.11.4\lib\net452\RestSharp.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.ServiceModel.Activation" />
<Reference Include="System.ServiceModel.Web" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="bean\Agv_Info.cs" />
<Compile Include="bean\Job.cs" />
<Compile Include="bean\JobStep.cs" />
<Compile Include="bean\job\ChargeJob.cs" />
<Compile Include="bean\job\EnterLeaveShelfJob.cs" />
<Compile Include="bean\job\SendFullShelfToLineJob.cs" />
<Compile Include="bean\job\GoFullShelfStationJob.cs" />
<Compile Include="bean\job\EmptyShelfBackJob.cs" />
<Compile Include="bean\job\EmptyAGVBackJob.cs" />
<Compile Include="bean\job\GoEmptyShelfLineJob.cs" />
<Compile Include="bean\Node.cs" />
<Compile Include="bean\node\ClientNode.cs" />
<Compile Include="bean\node\DoubleLineNodeFor4D.cs" />
<Compile Include="bean\node\DoubleLineNodeFor4C.cs" />
<Compile Include="BLL\AGVManager.cs" />
<Compile Include="BLL\AgvServer.cs" />
<Compile Include="BLL\Common.cs" />
<Compile Include="BLL\ConfigAppSettings.cs" />
<Compile Include="BLL\Control.cs" />
<Compile Include="BLL\HttpHelper.cs" />
<Compile Include="BLL\IniHelper.cs" />
<Compile Include="BLL\JsonHelper.cs" />
<Compile Include="BLL\MyWebClient.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="BLL\LineWebService.cs" />
<Compile Include="FrmMain.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="FrmMain.Designer.cs">
<DependentUpon>FrmMain.cs</DependentUpon>
</Compile>
<Compile Include="BLL\MiR_API.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="FrmMain.resx">
<DependentUpon>FrmMain.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Content Include="line.ico" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file \ No newline at end of file
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<log4net>
<appender name="AgvServer" type="log4net.Appender.RollingFileAppender">
<file value="logs/AgvServer.log"/>
<param name="Encoding" value="UTF-8"/>
<appendToFile value="true"/>
<rollingStyle value="Date"/>
<datePattern value="yyyy-MM-dd"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="[%date][%t][%c:%L]%-5p %m%n"/>
</layout>
</appender>
<appender name="LineWebService" type="log4net.Appender.RollingFileAppender">
<file value="logs/LineWebService.log"/>
<param name="Encoding" value="UTF-8"/>
<appendToFile value="true"/>
<rollingStyle value="Date"/>
<datePattern value="yyyy-MM-dd"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="[%date][%t][%c:%L]%-5p %m%n"/>
</layout>
</appender>
<logger name ="LineWebService">
<level value="Info"/>
<appender-ref ref="LineWebService"/>
</logger>
<root>
<level value="Info"/>
<appender-ref ref="AgvServer"/>
</root>
</log4net>
<appSettings>
<add key="ITS" value="http://10.85.17.233/ESMTCommonInterface/CommonService.asmx/VMIGetBoxDestInfo?boxRFID=" />
<add key="WebService" value="http://127.0.0.1/BenQMIR/Webservice/AGVService.asmx/" />
<add key="http.server" value="http://10.85.199.25/myproject/" />
<add key="FLEET" value="10.85.199.3" />
<add key="AutoCharge" value="True" />
<add key="ChargeWait" value="1" />
<add key="ChargeThreshold" value="20,70" />
</appSettings>
</configuration>
\ No newline at end of file \ No newline at end of file
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AGVControl;
using RestSharp;
namespace BLL
{
public class AGVManager
{
private static string Addr_CurSO = "/rest/api/qisda/device/currentOutLine";
/// <summary>
/// 查询当前出料工单信息
/// </summary>
/// <returns></returns>
public static bool FindCurSO(out WOData woData)
{
woData = null;
try
{
Dictionary<string, string> paramMap = new Dictionary<string, string>();
//paramMap.Add("deviceAlarmList", msgListStr);
string server = GetAddr(Addr_CurSO, paramMap);
DateTime startTime = DateTime.Now;
string resultStr = HttpHelper.Get(server);
Common.log.Debug("当前正在出工单料信息【" + server + "】【" + resultStr + "】");
WorkOrder workOrder = JsonHelper.DeserializeJsonToObject<WorkOrder>(resultStr);
if (workOrder == null)
{
return false;
}
else
{
if (workOrder.data == null)
{
return false;
}
else
{
if(workOrder.data.line !=null)
{
string tempLocation = workOrder.data.line;
if (workOrder.data.line.Equals("Feeder"))
{
tempLocation = "FeederIn";
}
else if (workOrder.data.line.Equals("4CFeeder"))
{
tempLocation = "4CFeederIn";
}
workOrder.data.line = tempLocation;
woData = workOrder.data;
return true;
}
}
}
}
catch (Exception ex)
{
Common.log.Error(ex);
return false;
}
return false;
}
/// <summary>
/// 当前正在出的工单信息
/// </summary>
public class WorkOrder
{
//{"code":0,"msg":"ok","data":{"hSerial":"32622","line":null,"so":"2506287"}}
//{"code":0,"msg":"ok","data":{"hSerial":"32651","line":"D2","so":"2508551"}}
public int code { get; set; }
public string msg { get; set; }
public WOData data { get; set; }
}
public class WOData
{
public string hSerial { get; set; }
public string line { get; set; }
public string so { get; set; }
public string ToTxt(string nodeName)
{
return string.Format("[hSerial={0},line={1}[{3}],so={2}]", hSerial,line,so,nodeName);
}
}
public static string A6_Target = "";
/// <summary>
/// 查找满料架目的地
/// </summary>
/// <param name="rfid"></param>
/// <param name="dest"></param>
/// <returns></returns>
public static bool FindFullShelfTarget(string rfid, out BoxDestInfo dest)
{
dest = null;
A6_Target = "";
try
{
if (rfid.Equals("") || rfid.Equals("00"))
return false;
string url = Common.itsHttp + rfid;
var client = new RestClient(url) { Timeout = -1 };
var request = new RestRequest(Method.GET);
//request.AddHeader("Host", "10.85.17.233");
IRestResponse response = client.Execute(request);
string json = response.Content;
json = json.Replace("\r", "");
json = json.Replace("\n", "");
json = json.Replace(" ", "");
Common.log.Debug("ITS URL: " + url + " Return: " + json);
if (string.IsNullOrWhiteSpace(json)) return false;
List<BoxDestInfo> res = JsonHelper.DeserializeJsonToList<BoxDestInfo>(json);
//JavaScriptSerializer serializer = new JavaScriptSerializer();
if (res == null || res.Count == 0)
return false;
string tempLocation = res[0].location;
if (res[0].id == rfid)
{
if (res[0].location.Equals("Feeder"))
{
tempLocation = "FeederIn";
}
else if (res[0].location.Equals("4CFeeder"))
{
tempLocation = "4CFeederIn";
}
if (Common.GetNodeNameByLineName(tempLocation, out string loc))
{
int i = Common.FindNode(loc);
if (i > -1)
{
#region 检查是否有空料架要出,有则先出空料架
//foreach (var item in Common.missionManager.missionList)
//{
// if (loc.Equals(item.NodeName))
// {
// Common.LogInfo("节点[" + loc + "]当前有空架任务,延迟A6出满料架任务[" + rfid + "]", false);
// return false;
// }
//}
//if (Common.nodeInfo[i].AgvName.Equals("").Equals(false))//有小车在目标任务点(限制4C车间),等待结束后再接任务
//{
// Common.LogInfo("节点[" + loc + "]当前有任务,延迟A6出满料架任务[" + rfid + "]", false);
// return false;
//}
//检查是否有车接到满料架任务,有则不再重复分配
//int id = Common.agvInfo.FindIndex(s => s.RFID == rfid);
//if (id > -1)
//{
// Common.LogInfo(Common.agvInfo[i].Name + " 正在执行满料架任务:目的地为 " + loc + " [产线名 " + res[0].location + "],不可重复分配小车");
// return false;
//}
#endregion
res[0].location = loc;
dest = res[0];
Common.GetLineNameByNodeName(loc,out string line);
A6_Target = res[0].ShowInfo(line);
Common.log.Debug("查找满料架任务[RFID=" + rfid + "]:目的地为 " + loc + " [产线名 " + line + "]");
return true;
}
else
{
Common.LogInfo("节点[" + loc + "]不存在或者未开启调用");
return false;
}
}
}
//[{"msg":"0料车已解绑或未发新料"}]
A6_Target = json;
return false;
}
catch (Exception ex)
{
Common.log.Error("FindA6Destination", ex);
return false;
}
}
public class BoxDestInfo
{
/// <summary>
/// RFID
/// </summary>
public string id { get; set; }
public string SO { get; set; }
public string location { get; set; }
public string ShowInfo(string loc)
{
return string.Format("RFID={0},SO={1},location={2}[{3}]", id, SO, loc,location);
}
}
/// <summary>
/// 物料到产线状态上报
/// </summary>
/// <param name="rfid"></param>
/// <param name="lineName"></param>
/// <returns></returns>
public static bool UpdateStatus(string rfid, string nodeName)
{
//GET /ESMTCommonInterface/CommonService.asmx/UpdateStatusBy?id=string&location=string HTTP/1.1
//Host: 10.85.17.233
Common.GetLineNameByNodeName(nodeName, out string lineName);
if (lineName.Equals("FeederIn"))
{
lineName = "Feeder";
}
else if (lineName.Equals("4CFeederIn"))
{
lineName = "4CFeeder";
}
string addr = "http://10.85.17.233/ESMTCommonInterface/CommonService.asmx/UpdateStatusBy?id=" + rfid + "&location=" + lineName;
//[{"msg":"1更新成功"}]
try
{
string result = HttpHelper.Get(addr);
Common.LogInfo(string.Format("[{0}] [{1}]", addr, result));
if (!result.Equals(""))
{
List<Msg> msgs = JsonHelper.DeserializeJsonToList<Msg>(result);
if (msgs == null || msgs.Count == 0)
return false;
bool resRtn = int.TryParse(msgs[0].msg.Substring(0, 1), out int resCode);
if (resRtn)
{
if (resCode.Equals(1))
{
Common.LogInfo(string.Format("产线{0} 物料状态更新成功[{1}]", lineName, rfid));
return true;
}
else
return false;
}
return false;
}
}
catch { return false; }
return false;
}
/// <summary>
/// 获取大料架解绑情况
/// </summary>
/// <param name="rfid"></param>
/// <param name="lineName">产线名称</param>
/// <returns></returns>
public static bool GetRackBy(string rfid, out string lineName)
{
lineName = "";
//GET /ESMTCommonInterface/CommonService.asmx/GetRackBy?id=string HTTP/1.1
//Host: 10.85.17.233
string addr = "http://10.85.17.233/ESMTCommonInterface/CommonService.asmx/GetRackBy?id=" + rfid;
//[{"msg":"1OKD1"}]
//[{"msg":"0NGFeeder"}]
try
{
string result = HttpHelper.Get(addr);
if (!result.Equals(""))
{
List<Msg> msgs = JsonHelper.DeserializeJsonToList<Msg>(result);
if (msgs == null || msgs.Count == 0)
return false;
int.TryParse(msgs[0].msg.Substring(0, 1), out int resCode);
string resStr = msgs[0].msg.Substring(1, 2);
lineName = msgs[0].msg.Substring(3);
Common.log.Debug(string.Format("[{0}] [{1}]", addr, result));
if (lineName.Equals("").Equals(true))
return false;
if (resStr.Equals("OK") || resCode.Equals(1))
return true;
else
return false;
}
}
catch (Exception ex)
{
Common.log.Error(ex.Message);
return false;
}
return false;
}
public static string GetRackBy(string rfid)
{
//GET /ESMTCommonInterface/CommonService.asmx/GetRackBy?id=string HTTP/1.1
//Host: 10.85.17.233
string addr = "http://10.85.17.233/ESMTCommonInterface/CommonService.asmx/GetRackBy?id=" + rfid;
//[{"msg":"1OKD1"}]
//[{"msg":"0NGFeeder"}]
try
{
string result = HttpHelper.Get(addr);
if (!result.Equals(""))
{
List<Msg> msgs = JsonHelper.DeserializeJsonToList<Msg>(result);
if (msgs == null || msgs.Count == 0)
return "";
return result;
}
}
catch (Exception ex)
{
Common.log.Error(ex.Message);
return "";
}
return "";
}
/// <summary>
/// 大料架接口回复
/// </summary>
public class Msg
{
public string msg { get; set; }
}
private static string Addr_updateDeviceAlarmMsg = "/rest/api/qisda/device/updateDeviceAlarmMsg";
/// <summary>
/// 异常看板
/// </summary>
/// <param name="msgList"></param>
/// <returns></returns>
public static string updateDeviceAlarmMsg(List<AlarmMsg> msgList)
{
string msg = "";
try
{
Dictionary<string, string> paramMap = new Dictionary<string, string>();
string msgListStr = JsonHelper.SerializeObject(msgList);
paramMap.Add("deviceAlarmList", msgListStr);
string server = GetAddr(Addr_updateDeviceAlarmMsg, paramMap);
DateTime startTime = DateTime.Now;
string resultStr = HttpHelper.Post(server, "");
Common.log.Debug("异常看板【" + server + "】【" + resultStr + "】");
RfidData data = JsonHelper.DeserializeJsonToObject<RfidData>(resultStr);
if (data == null)
{
return msg = " updateDeviceAlarmMsg 没有收到服务器反馈";
}
else if (data.code.Equals(0).Equals(false))
{
return msg = "【" + server + "】【" + resultStr + "】" + data.msg;
}
return "";
}
catch (Exception ex)
{
Common.log.Error(ex);
}
return msg;
}
private static string GetAddr(string addr, Dictionary<string, string> paramsMap)
{
string server = ConfigAppSettings.GetValue("http.server");
if (server.EndsWith("/"))
{
server = server.Substring(0, server.Length - 1);
}
string path = server + addr.Trim() + "?";
foreach (string paramName in paramsMap.Keys)
{
string par = System.Web.HttpUtility.UrlEncode(paramsMap[paramName], System.Text.Encoding.UTF8);
path += paramName + "=" + par + "&";
}
path = path.Substring(0, path.Length - 1);
return path;
}
public static string Add_emptyMsg = "http://10.85.199.1/BenQMIR/Webservice/AGVService.asmx/CreateEmptyRecycleTask";//"http://localhost:11111/BenQMIR/Webservice/AGVService.asmx/CreateEmptyRecycleTask";//
public static string CreateEmptyTask()
{
try
{
Dictionary<string, string> paramMap = new Dictionary<string, string>();
paramMap.Add("emptyStation", "D1");
string path = Add_emptyMsg + "?";
foreach (string paramName in paramMap.Keys)
{
string par = System.Web.HttpUtility.UrlEncode(paramMap[paramName], System.Text.Encoding.UTF8);
path += paramName + "=" + par + "&";
}
path = path.Substring(0, path.Length - 1);
string resultStr = HttpHelper.Post(path, "");
Common.log.Debug("【" + path + "】【" + resultStr + "】");
Result data = JsonHelper.DeserializeJsonToObject<Result>(resultStr);
if (data == null)
{
return " updateDeviceAlarmMsg 没有收到服务器反馈";
}
else
{
return data.Succeed.ToString();
}
}
catch (Exception e)
{
return e.ToString();
}
}
}
public class ShelfLockInfo
{
//返回: {"code":0,"msg":"ok","data":
//[{"barcode":"S20052301213","cid":"packing-20","rfid":"A12","rfidLoc":"3","lockPos":"4D2001AA0006","lockPosId":"1231"}]}
/// <summary>
/// 返回码,0为正常,其他为异常
/// </summary>
public int code { get; set; }
/// <summary>
/// 消息
/// </summary>
public string msg { get; set; }
public List<ShelfLockData> data { get; set; }
}
public class ShelfLockData
{
/// <summary>
/// 库位中料盘的条码
/// </summary>
public string barcode { get; set; }
/// <summary>
/// 库位中料盘的锁定库位对应的料仓编
/// </summary>
public string cid { get; set; }
/// <summary>
/// 料架RFID
/// </summary>
public string rfid { get; set; }
/// <summary>
/// 料架的库位
/// </summary>
public int rfidLoc { get; set; }
/// <summary>
/// 库位中料盘的锁定库位
/// </summary>
public string lockPos { get; set; }
/// <summary>
/// 料架出库的剩余数量
/// </summary>
public int taskCount { get; set; }
}
/// <summary>
/// 获取料架中的任务数
/// </summary>
public class ShelfTaskCount
{
// {"code":0,"msg":"ok","data":{"taskCount":0,"rfid":"A2"}}
/// <summary>
/// 0为正常,其他为异常
/// </summary>
public int code { get; set; }
/// <summary>
/// 消息
/// </summary>
public string msg { get; set; }
public ShelfTaskData shelfTaskData { get; set; }
}
public struct ShelfTaskData
{
/// <summary>
/// 当前料架剩余任务数(即还有几盘料没放上去)
/// </summary>
public int taskCount { get; set; }
/// <summary>
/// 料架RFID
/// </summary>
public string rfid { get; set; }
}
public class AlarmMsg
{
//>>>name : 异常位置名称
public string name = "";
//>>>msgKey : 异常信息唯一标识
public string msgKey = "";
//>>>msgValue : 异常信息
public string msgValue = "";
//0:异常;1:正常显示
public int type = 0;
/// <summary>
/// 异常信息
/// </summary>
/// <param name="name">异常位置名称</param>
/// <param name="key">异常信息唯一标识</param>
/// <param name="value">异常信息</param>
public AlarmMsg(string name, string key, string value,int type=0)
{
this.name = name;
this.msgKey = key;
this.msgValue = value;
this.type = type;
}
}
public class RfidData
{
//{"code":0,"msg":"ok","data":"7"}
public int code { get; set; }
public string msg { get; set; }
public Dictionary<string, string> data { get; set; }
}
/// <summary>
/// Mir位置
/// </summary>
public class MirPosition
{
/// <summary>
/// 位置名称
/// </summary>
public string name { get; set; }
/// <summary>
/// X轴方位
/// </summary>
public double orientation { set; get; }
/// <summary>
/// x轴
/// </summary>
public double pos_x { get; set; }
public double pos_y { get; set; }
}
}
using AGVControl;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace BLL
{
/// <summary>
/// AGV服务端
/// </summary>
public class AgvServer
{
private bool _loop;
private Socket _server; //服务端
private List<Client> _client; //所有客户端
private Thread tListenClient; //监听客户端连接
public const int PORT = 9501; //端口
private Thread tPingClient; //ping
/// <summary>
/// 节点改变事件
/// </summary>
/// <param name="nodeIndex"></param>
public delegate void NodeChangedEvent(int nodeIndex);
/// <summary>
/// 节点改变
/// </summary>
public event NodeChangedEvent NodeChanged;
/// <summary>
/// 节点在线
/// </summary>
public event NodeChangedEvent NodeOnline;
/// <summary>
/// AGV服务端
/// </summary>
public AgvServer()
{
_client = new List<Client>();
}
/// <summary>
/// 开启服务
/// </summary>
public void Start()
{
try
{
IPEndPoint localEP = new IPEndPoint(IPAddress.Any, PORT);
_server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_server.Bind(localEP);
_server.Listen(100);
Common.log.Info("Server Start");
_loop = true;
_client = new List<Client>();
tListenClient = new Thread(new ThreadStart(ListenClient));
tListenClient.Start();
tPingClient = new Thread(new ThreadStart(KeepLiveClient));
tPingClient.Start();
}
catch (Exception ex)
{
Common.log.Error("Start()", ex);
}
}
/// <summary>
/// 停止服务
/// </summary>
public void Stop()
{
_loop = false;
for (int i = 0; i < _client.Count; i++)
{
_client[i].Loop = false;
_client[i].IsConn = false;
_client[i].Socket.Close();
}
_server.Close();
_client = null;
Thread.Sleep(50);
Common.LogInfo("Server Stop");
}
public Dictionary<string, DateTime> readyEnterTime = new Dictionary<string, DateTime>();
public Dictionary<string, DateTime> readyLeaveTime = new Dictionary<string, DateTime>();
public bool ReadyEnter(string nodeName, string rfid = "")
{
int nodeIdx = Common.nodeInfo.FindIndex(s => s.Name == nodeName);
string ip = Common.nodeInfo[nodeIdx].IP;
int idx = FindClient(ip);
if (idx == -1)
{
Common.LogInfo("ReadyEnter 没有找到" + nodeName + " " + ip);
return false;
}
else
{
try
{
if (!readyEnterTime.ContainsKey(nodeName))
{
readyEnterTime.Add(nodeName, DateTime.Now);
}
else
{
TimeSpan timeSpan = DateTime.Now - readyEnterTime[nodeName];
if (timeSpan.TotalSeconds < 45)
{
Common.log.Debug(nodeName + " " + ip + " ReadyEnter 45秒内不重复发送");
return false;
}
else if (timeSpan.TotalMinutes > 2)
{
readyEnterTime[nodeName] = DateTime.Now;
}
}
}
catch(Exception ex) { Common.log.Debug(ex.Message +";"+ex.StackTrace); }
ClientNode node = new ClientNode(nodeName, rfid, eNodeStatus.ReadyEnter);
byte[] buff = Encode(node);
return Send(idx, buff);
}
}
public bool ReadyLeave(string nodeName, string rfid = "")
{
int nodeIdx = Common.nodeInfo.FindIndex(s => s.Name == nodeName);
string ip = Common.nodeInfo[nodeIdx].IP;
int idx = FindClient(ip);
if (idx == -1)
{
Common.LogInfo("ReadyLeave 没有找到" + nodeName + " " + ip);
return false;
}
else
{
try
{
if (!readyLeaveTime.ContainsKey(nodeName))
{
readyLeaveTime.Add(nodeName, DateTime.Now);
}
else
{
TimeSpan timeSpan = DateTime.Now - readyLeaveTime[nodeName];
if (timeSpan.TotalSeconds < 45)
{
Common.log.Debug(nodeName + " " + ip + " ReadyLeave 45秒内不重复发送");
return false;
}
else if (timeSpan.TotalMinutes > 3)
{
readyLeaveTime[nodeName] = DateTime.Now;
}
}
}
catch (Exception ex) { Common.log.Debug(ex.Message + ";" + ex.StackTrace); }
ClientNode node = new ClientNode(nodeName, rfid, eNodeStatus.ReadyLeave);
byte[] buff = Encode(node);
return Send(idx, buff);
}
}
public bool FinishEnter(string nodeName, string rfid = "")
{
int nodeIdx = Common.nodeInfo.FindIndex(s => s.Name == nodeName);
string ip = Common.nodeInfo[nodeIdx].IP;
int idx = FindClient(ip);
if (idx == -1)
{
Common.LogInfo("FinishEnter 没有找到" + nodeName + " " + ip);
return false;
}
else
{
ClientNode node = new ClientNode(nodeName, rfid, eNodeStatus.FinishEnter);
byte[] buff = Encode(node);
return Send(idx, buff);
}
}
public bool FinishLeave(string nodeName, string rfid = "")
{
int nodeIdx = Common.nodeInfo.FindIndex(s => s.Name == nodeName);
string ip = Common.nodeInfo[nodeIdx].IP;
int idx = FindClient(ip);
if (idx == -1)
{
Common.LogInfo("FinishLeave 没有找到" + nodeName + " " + ip);
return false;
}
else
{
ClientNode node = new ClientNode(nodeName, rfid, eNodeStatus.FinishLeave);
byte[] buff = Encode(node);
return Send(idx, buff);
}
}
private void KeepLiveClient()
{
int n;
while (_loop)
{
n = 0;
while (n < 5000) //所有产线间隔
{
Thread.Sleep(50);
n += 50;
if (!_loop) return;
}
foreach (ClientNode clientNode in Common.nodeInfo)
{
n = 0;
while (n < 300) //每条产线间隔
{
Thread.Sleep(50);
n += 50;
if (!_loop) return;
}
int idx = FindClient(clientNode.IP);
if (idx == -1)
{
Common.log.Debug("KeepLive 没有找到" + clientNode.Name);
int index = Common.nodeInfo.IndexOf(clientNode);
Common.nodeInfo[index].Online = false;
continue;
}
else
{
if (clientNode.StateEquals(eNodeStatus.None))
{
byte[] buff = new byte[] { 0X00, 0X00 };
int index = Common.nodeInfo.IndexOf(clientNode);
if (!Send(idx, buff))
{
Common.nodeInfo[index].Online = false;
Common.log.Debug(clientNode.Name + " KeepLive 发送失败");
}
else
{
Common.nodeInfo[index].Online = true;
Common.log.Debug(clientNode.Name + " KeepLive 发送成功");
}
}
}
NodeOnline?.Invoke(Common.nodeInfo.IndexOf(clientNode));
NodeChanged?.Invoke(Common.nodeInfo.IndexOf(clientNode));
}
//for (int i = 0; i < Common.nodeInfo.Count; i++)
//{
// try
// {
// if (!_loop)
// break;
// if (!Common.nodeInfo[i].IP.Equals(""))
// Common.nodeInfo[i].Online = CheckIP(Common.nodeInfo[i].Name, Common.nodeInfo[i].IP);
// NodeOnline?.Invoke(i);
// NodeChanged?.Invoke(i);
// }
// catch (Exception e)
// {
// Common.log.Error("PingClient", e);
// }
//}
}
}
public bool CheckIP(string name, string ip)
{
//IP合法
string pattern = @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$";
bool rtn = System.Text.RegularExpressions.Regex.IsMatch(ip, pattern);
if (!rtn)
{
Common.LogInfo("非法的IP地址" + ip);
return false;
}
//Ping服务端
try
{
System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
System.Net.NetworkInformation.PingReply result = ping.Send(ip, 2000);
ping.Dispose();
if (result.Status != System.Net.NetworkInformation.IPStatus.Success)
{
Common.log.Debug(name + " Ping " + ip + " 请求没有响应");
return false;
}
return true;
}
catch (Exception ex)
{
Common.log.Error("CheckIP", ex);
return false;
}
}
/// <summary>
/// 监听客户端
/// </summary>
private void ListenClient()
{
while (_loop)
{
try
{
Socket socket = _server.Accept(); //这边会暂停,不需要sleep
IPEndPoint ep = (IPEndPoint)socket.RemoteEndPoint;
Thread listen = new Thread(new ParameterizedThreadStart(ListenNet));
//string ip = ep.Address.ToString();
//if (ip == System.Configuration.ConfigurationManager.AppSettings["LocalIP"])
// ip += ":" + ep.Port;
//新的客户端
Client client = new Client
{
IP = ep.Address.ToString() + ":" + ep.Port,
Loop = true,
IsConn = true,
Socket = socket,
ListenNet = listen,
nodeName = new List<string>(),
};
//重连后关闭旧连接
//int idx = _client.FindIndex(s => s.IP.Equals(ip));
//if (idx > -1)
//{
// _client[idx].IsConn = false;
// _client[idx].nodeName.Clear();
// _client[idx].Loop = false;
// _client[idx].Socket.Close();
// _client.RemoveAt(idx);
//}
_client.Add(client);
listen.Start(_client.Count - 1);
Common.log.Debug(string.Format("[{0}] 已连接", client.IP));
}
catch (SocketException)
{
//关闭连接,退出阻塞Accept
Common.LogInfo("服务端关闭连接,退出阻塞Accept");
}
catch (Exception ex)
{
Common.log.Error("ListenClient()", ex);
}
}
}
/// <summary>
/// 客户端数据接收
/// </summary>
/// <param name="obj">索引</param>
private void ListenNet(object obj)
{
int sleep = 50;
Client client = _client[(int)obj];
byte[] temp = new byte[200];
int time = 0;
while (client.Loop)
{
Thread.Sleep(sleep);
try
{
if (!client.Loop) break;
if (client.Socket.Available > 0)
{
time = 0;
int count = client.Socket.Receive(temp);
byte[] buff = new byte[count];
Array.Copy(temp, 0, buff, 0, count);
ClientNode node = Decode(client, buff);
if (node == null)
{
Common.log.Debug(client.IP + " 解码失败:" + HexBuff(buff));
}
else
{
Common.log.Debug(client.IP + " 解码内容:" + HexBuff(buff));
Common.log.Debug("Receive[" + client.IP + "] " + node.StatetText());
int idx = client.nodeName.FindIndex(s => s == node.Name);
if (idx == -1) client.nodeName.Add(node.Name);
UpdateNode(node);
}
}
else
{
time += sleep;
if (time > 120000)
{
Offline(client);
Common.log.Debug("[" + client.IP + "] 超过2分钟没有收到数据,关闭连接");
}
}
}
catch (Exception ex)
{
Common.log.Error("ListenNet()", ex);
}
}
}
/// <summary>
/// 编码
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
private byte[] Encode(ClientNode node)
{
int idx = 0;
byte[] buff = new byte[12];
buff[idx++] = 0xAD;
buff[idx++] = (byte)node.Name[0];
buff[idx++] = Convert.ToByte(node.Name.Substring(1));
buff[idx++] = (byte)node.RFID[0];
//buff[idx++] = 0X00;
//buff[idx++] = 0X00;
//buff[idx++] = 0X00;
buff[idx++] = Convert.ToByte(node.RFID.Substring(1));
buff[idx++] = (byte)node.GetState();
buff[idx++] = 0;
idx += 4; //预留
buff[idx] = 0xDA;
return buff;
}
/// <summary>
/// 解码
/// </summary>
/// <param name="buff"></param>
/// <returns></returns>
private ClientNode Decode(Client client, byte[] buff)
{
int idx = 0;
string name = "";
string rfid = "";
if (buff[idx++] != 0xAD) return null;
if (buff[idx] == 0x00 && buff[idx + 1] == 0x00)//收到产线
{
int k = Common.nodeInfo.FindIndex(s => client.IP.Contains(s.IP) && !s.Name.StartsWith("A"));
if (k > -1)
{
name = Common.nodeInfo[k].Name;
rfid = "";
}
idx += 2;
idx += 2;
}
else
{
name = (char)buff[idx] + buff[idx + 1].ToString();
idx += 2;
rfid = (char)buff[idx] + buff[idx + 1].ToString();
idx += 2;
}
eNodeStatus action = (eNodeStatus)buff[idx++];
ClientLevel level = (ClientLevel)buff[idx++];
idx += 4; //预留
if (buff[idx] != 0xDA) return null;
ClientNode node = new ClientNode(name, rfid, action);
node.ClientLevel = level;
return node;
}
private void UpdateNode(ClientNode node)
{
int idx = Common.nodeInfo.FindIndex(s => s.Name == node.Name);
if (idx == -1)
{
Common.log.Error("UpdateNode " + node.Name + " 不存在");
return;
}
if (!Common.nodeInfo[idx].Online)
{
Common.nodeInfo[idx].Online = true;
NodeOnline?.Invoke(idx);
}
if (!Common.nodeInfo[idx].StateEquals(node.GetState()) ||
Common.nodeInfo[idx].RFID != node.RFID || Common.nodeInfo[idx].ClientLevel != node.ClientLevel)
{
Common.nodeInfo[idx].UpdateNodeStatus(node.GetState());
Common.nodeInfo[idx].ClientLevel = node.ClientLevel;
Common.nodeInfo[idx].RFID = node.RFID;
Common.LogInfo("节点更新 " + node.StatetText());
NodeChanged?.Invoke(idx);
}
}
private void Offline(Client client)
{
client.Loop = false;
client.IsConn = false;
client.Socket.Close();
for (int i = 0; i < client.nodeName.Count; i++)
{
int idx = Common.nodeInfo.FindIndex(s => s.Name == client.nodeName[i]);
if (idx == -1) continue;
Common.nodeInfo[idx].Offline();
NodeChanged(idx);
NodeOnline(idx);
}
client.nodeName.Clear();
//_client.Remove(client);
}
/// <summary>
/// 16进制
/// </summary>
/// <param name="buff"></param>
/// <returns></returns>
private string HexBuff(byte[] buff)
{
string s = "";
if (buff == null) return s;
for (int i = 0; i < buff.Length; i++)
s += buff[i].ToString("X2") + " ";
return s;
}
/// <summary>
/// 查找客户端
/// </summary>
/// <param ip="ip">ip地址</param>
/// <returns></returns>
private int FindClient(string ip)
{
int index = -1;
if (_client == null) return index;
try
{
foreach (Client item in _client)
{
if (item.IsConn)
{
//Common.log.Info("已连接客户端:" + string.Join("#", item.IP));
if (item.IP.Contains(ip))
{
index = _client.IndexOf(item);
break;
}
//int idx = item.nodeName.FindIndex(a => a == name);
//if (idx != -1)
//{
// index = _client.IndexOf(item);
// break;
//}
}
}
}
catch { };
return index;
}
/// <summary>
/// 发送命令
/// </summary>
/// <param name="idx"></param>
/// <param name="buff"></param>
/// <returns></returns>
private bool Send(int idx, byte[] buff)
{
string ip = "[" + _client[idx].IP + "]";
if (!_client[idx].IsConn)
{
Common.log.Error(ip + " 没有连接");
return false;
}
try
{
if (_client[idx].IsConn)
_client[idx].Socket.Send(buff);
Common.log.Debug("SendTo" + ip + ": " + HexBuff(buff));
return true;
}
catch (Exception ex)
{
Common.log.Debug("Send Error: " + ip, ex);
return false;
}
}
}
}
\ No newline at end of file \ No newline at end of file
using BLL;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading;
using System.Web.UI.WebControls;
using System.Windows.Forms;
namespace AGVControl
{
public static class SettingString
{
public const int AGVCNT = 6;
public const string Move = "Move";
//任务名称
public const string Standby = "Standby";
public const string CheckShelf = "CheckShelf";
public const string DoorDToC = "DoorDToC";
public const string DoorCToD = "DoorCToD";
public const string DoubleLine_Name_Prefix = "A";
public const string Wait = "Wait";
public const string Done = "Done";
public const string Aborted = "Aborted";
public const string AutoCharge = "AutoCharge";
public const string Executing = "Executing";
public const string RandomCharge_IP1 = "10.85.199.80";
public const string RandomCharge_IP2 = "10.85.199.81";
public const string RandomCharge_IP3 = "10.85.199.71";
public const string RandomCharge_IP4 = "10.85.199.74";
public const string FileName_AGV = "AgvName.csv";
public const string FileName_AgvMission = "AgvMission.csv";
public const string FileName_AgvProductionLine = "AgvProductionLine.csv";
public const string FileName_tempData = "tempData.ini";
public const string IsUse = "IsUse";
public const string RFID = "RFID";
public const string EmptyShelfCnt = "EmptyShelfCnt";
/// <summary>
/// 去4C的3辆车IP
/// </summary>
public const string C4_AGV_IPs = "10.85.199.71,10.85.199.72,10.85.199.73";
public const string C4_STANDBY1 = "C4_STANDBY1";
public const string C4_STANDBY2 = "C4_STANDBY2";
public const string C4FeederIn = "C21";
public const string D4FeederIn = "D21";
public const string C4FeederOut = "C22";
public const string D4FeederOut = "D22";
/// <summary>
/// 上料区
/// </summary>
public const string A6 = "A6";
/// <summary>
/// 下料区
/// </summary>
public const string A5 = "A5";
public const string D4_Name_Prefix = "D";
public const string C4_Name_Prefix = "C";
}
/// <summary>
/// 公共参数
/// </summary>
public static class Common
{
/// <summary>
/// 节点信息
/// </summary>
public static List<ClientNode> nodeInfo;
/// <summary>
/// 小车信息
/// </summary>
public static List<Agv_Info> agvInfo;
public static System.Windows.Forms.TextBox logTextBox;
public static System.Windows.Forms.DataGridView missionView;
public static AgvServer server;
public static BLL.Control control;
public static MiR_API mir;
public static WebService web;
public static ChargeStatus chargeStatus;
public static string itsHttp;
public static log4net.ILog log;
public static Dictionary<string, string> agvMission;
public static Dictionary<string, string> showNameMissionName;
//public static Dictionary<string, string> agvProductionLine;
public static System.Configuration.Configuration appConfig;
public static MissionManager missionManager;
public static StandbyStation StandbyStation = new StandbyStation() { C4_Station1 = "", C4_Station2 = "" };
private static List<string> msg = new List<string>();
private static string preLog = "";
public static readonly string CONFIG_PATH = AppDomain.CurrentDomain.BaseDirectory + "Config\\";
public static string ReadIni(string section, string key)
{
return IniHelper.ReadValue(section, key, CONFIG_PATH + SettingString.FileName_tempData);
}
public static void WriteIni(string section, string key, string value)
{
IniHelper.WriteValue(section, key, value, CONFIG_PATH + SettingString.FileName_tempData);
}
public static bool GetNodeNameByLineName(string lineName, out string nodeName)
{
nodeName = "";
int id = nodeInfo.FindIndex(s => s.LineName.Equals(lineName));
if (id > -1)
{
nodeName = nodeInfo[id].Name;
return true;
}
else
{
return false;
}
}
public static bool GetLineNameByNodeName(string nodeName, out string lineName)
{
lineName = "";
int id = nodeInfo.FindIndex(s => s.Name.Equals(nodeName));
if (id > -1)
{
lineName = nodeInfo[id].LineName;
return true;
}
else
{
return false;
}
}
/// <summary>
/// 查找节点是否存在以及是否调用
/// </summary>
/// <param name="nodeName">节点名称</param>
/// <returns></returns>
public static int FindNode(string nodeName)
{
int idx = Common.nodeInfo.FindIndex(s => s.Name.Equals(nodeName) && s.IsUse);
return idx;
}
/// <summary>
/// 移动到节点位置
/// </summary>
/// <param name="agv"></param>
/// <param name="nodeName"></param>
/// <returns></returns>
public static bool MoveToNode(Agv_Info agv, string nodeName)
{
string log;
//清除目的地
agv.Place = "";
//执行下一个任务
bool rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission[SettingString.Move + nodeName]);
if (rtn)
{
agv.Place = nodeName;
log = string.Format("{0} {1} To Node {2}", agv.Name, SettingString.Move, nodeName);
Common.LogInfo(log);
Common.mir.State_Ready(agv);
}
else
{
log = string.Format("{0} {1} To Node {2} 失败", agv.Name, SettingString.Move, nodeName);
Common.LogInfo(log);
}
return rtn;
}
/// <summary>
/// 查看A5、A6需要料架的状况
/// </summary>
/// <param name="agv"></param>
/// <param name="node"></param>
public static bool CheckA5A6State(Agv_Info agv, eShelfType shelfType, out string nodeName)
{
bool rtn = false;
string place = agv.Place;
nodeName = "";
if (shelfType.Equals(eShelfType.SmallShelf))
{
int tarIdx = Common.nodeInfo.FindIndex(s => s.Name == SettingString.A5
&& (s.StateEquals(eNodeStatus.NeedD) || s.StateEquals(eNodeStatus.NeedEnter)) && s.IsUse);
if (tarIdx == -1)
{
Common.log.Debug(string.Format("{0} {1}不需要小料架", agv.Name, SettingString.A5));
}
else
{
tarIdx = Common.agvInfo.FindIndex(s=> !s.IP.Equals(agv.IP) && s.CurJob !=null && s.CurJob is EmptyShelfBackJob
&& ((((EmptyShelfBackJob)s.CurJob).EmptyShelfTargetPlace)!=null ) && ((EmptyShelfBackJob)s.CurJob).EmptyShelfTargetPlace.Equals(SettingString.A5));
if(tarIdx==-1)
{
nodeName = SettingString.A5;
Common.log.Debug(string.Format("{0} {1}需要小料架", agv.Name, SettingString.A5));
return true;
}
}
tarIdx = Common.nodeInfo.FindIndex(s => s.Name == SettingString.A6 &&
(s.StateEquals(eNodeStatus.NeedEnter) || s.StateEquals(eNodeStatus.NeedEnterLeave)) && s.IsUse);
if (tarIdx == -1)
{
Common.log.Debug(string.Format("{0} {1}不需要小料架", agv.Name, SettingString.A6));
//rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission[SettingString.MoveStandby]);
//if (rtn)
//{
// agv.NextPlace = "";
// agv.TaskSend = rtn ? SettingString.MoveStandby : "";
// agv.Msg = string.Format("{0} 在{1}已装载小料架,送往{2}", agv.Name, place, SettingString.MoveStandby);
// Common.LogInfo(string.Format("{0} 在{1}已装载小料架,送往{2}", agv.Name, place, SettingString.MoveStandby));
//}
}
else
{
tarIdx = Common.agvInfo.FindIndex(s => !s.IP.Equals(agv.IP) && s.CurJob != null && s.CurJob is EmptyShelfBackJob
&& ((((EmptyShelfBackJob)s.CurJob).EmptyShelfTargetPlace) != null) && ((EmptyShelfBackJob)s.CurJob).EmptyShelfTargetPlace.Equals(SettingString.A6));
if(tarIdx==-1)
{
nodeName = SettingString.A6;
Common.log.Debug(string.Format("{0} {1}需要小料架", agv.Name, SettingString.A6));
return true;
}
//rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission[SettingString.Move + SettingString.A6]);
//if (rtn)
//{
// agv.NextPlace = "";
// tarNodeName = SettingString.A6;
// Common.nodeInfo[tarIdx].AgvName = agv.Name;
// agv.TaskSend = rtn ? SettingString.Move + SettingString.A6 : "";
// agv.Msg = string.Format("{0} 在{1}已装载小料架,送往{2}", agv.Name, place, SettingString.A6);
// Common.LogInfo(string.Format("{0} 在{1}已装载小料架,送往{2}", agv.Name, place, SettingString.A6));
// return true;
//}
}
}
else if (shelfType.Equals(eShelfType.BigShelf))
{
int tarIdx = Common.nodeInfo.FindIndex(s => s.Name == SettingString.A5
&& (s.StateEquals(eNodeStatus.NeedC) || s.StateEquals(eNodeStatus.NeedEnter)) && s.IsUse);
if (tarIdx == -1)
{
Common.log.Debug(string.Format("{0} {1}不需要大料架", agv.Name, SettingString.A5));
}
else
{
tarIdx = Common.agvInfo.FindIndex(s => !s.IP.Equals(agv.IP) && s.CurJob != null && s.CurJob is EmptyShelfBackJob
&& ((((EmptyShelfBackJob)s.CurJob).EmptyShelfTargetPlace) != null) && ((EmptyShelfBackJob)s.CurJob).EmptyShelfTargetPlace.Equals(SettingString.A5));
if(tarIdx==-1)
{
nodeName = SettingString.A5;
Common.log.Debug(string.Format("{0} {1}需要大料架", agv.Name, SettingString.A5));
return true;
}
}
tarIdx = Common.nodeInfo.FindIndex(s => s.Name == SettingString.A6 &&
(s.StateEquals(eNodeStatus.NeedEnter) || s.StateEquals(eNodeStatus.NeedEnterLeave)) && s.IsUse);
if (tarIdx == -1)
{
Common.log.Debug(string.Format("{0} {1}不需要大料架", agv.Name, SettingString.A6));
//rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission[SettingString.MoveStandby]);
//if (rtn)
//{
// agv.NextPlace = "";
// agv.TaskSend = rtn ? SettingString.MoveStandby : "";
// agv.Msg = string.Format("{0} 在{1}已装载大料架,送往{2}", agv.Name, place, SettingString.MoveStandby);
// Common.LogInfo(string.Format("{0} 在{1}已装载大料架,送往{2}", agv.Name, place, SettingString.MoveStandby));
//}
}
else
{
tarIdx = Common.agvInfo.FindIndex(s => !s.IP.Equals(agv.IP) && s.CurJob != null && s.CurJob is EmptyShelfBackJob
&& ((((EmptyShelfBackJob)s.CurJob).EmptyShelfTargetPlace) != null) && ((EmptyShelfBackJob)s.CurJob).EmptyShelfTargetPlace.Equals(SettingString.A6));
if(tarIdx==-1)
{
nodeName = SettingString.A6;
Common.log.Debug(string.Format("{0} {1}需要大料架", agv.Name, SettingString.A6));
return true;
}
//rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission[SettingString.Move + SettingString.A6]);
//if (rtn)
//{
// agv.NextPlace = "";
// tarNodeName = SettingString.A6;
// Common.nodeInfo[tarIdx].AgvName = agv.Name;
// agv.TaskSend = rtn ? SettingString.Move + SettingString.A6 : "";
// agv.Msg = string.Format("{0} 在{1}已装载大料架,送往{2}", agv.Name, place, SettingString.A6);
// Common.LogInfo(string.Format("{0} 在{1}已装载大料架,送往{2}", agv.Name, place, SettingString.A6));
// return true;
//}
}
}
return false;
}
/// <summary>
/// 查看A5料架的状况(A5当前料架小于2个)
/// </summary>
/// <param name="agv"></param>
/// <param name="node"></param>
public static bool CheckA5State(Agv_Info agv, eShelfType shelfType, out string nodeName)
{
bool rtn = false;
string place = agv.Place;
nodeName = "";
if (shelfType.Equals(eShelfType.SmallShelf))
{
int tarIdx = Common.nodeInfo.FindIndex(s => s.Name == SettingString.A5 && s.ClientLevel.Equals(ClientLevel.High)
&& (s.StateEquals(eNodeStatus.NeedD) || s.StateEquals(eNodeStatus.NeedEnter)) && s.IsUse);
if (tarIdx == -1)
{
Common.log.Debug(string.Format("{0} {1}不需要小料架", agv.Name, SettingString.A5));
}
else
{
nodeName = SettingString.A5;
Common.log.Debug(string.Format("{0} {1}需要小料架", agv.Name, SettingString.A5));
return true;
}
//tarIdx = Common.nodeInfo.FindIndex(s => s.Name == SettingString.A6 &&
//(s.StateEquals(eNodeStatus.NeedEnter) || s.StateEquals(eNodeStatus.NeedEnterLeave)) && s.IsUse);
//if (tarIdx == -1)
//{
// Common.LogInfo(string.Format("{0} {1}不需要小料架", agv.Name, SettingString.A6));
// //rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission[SettingString.MoveStandby]);
// //if (rtn)
// //{
// // agv.NextPlace = "";
// // agv.TaskSend = rtn ? SettingString.MoveStandby : "";
// // agv.Msg = string.Format("{0} 在{1}已装载小料架,送往{2}", agv.Name, place, SettingString.MoveStandby);
// // Common.LogInfo(string.Format("{0} 在{1}已装载小料架,送往{2}", agv.Name, place, SettingString.MoveStandby));
// //}
//}
//else
//{
// nodeName = SettingString.A6;
// Common.LogInfo(string.Format("{0} {1}需要小料架", agv.Name, SettingString.A6));
// return true;
// //rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission[SettingString.Move + SettingString.A6]);
// //if (rtn)
// //{
// // agv.NextPlace = "";
// // tarNodeName = SettingString.A6;
// // Common.nodeInfo[tarIdx].AgvName = agv.Name;
// // agv.TaskSend = rtn ? SettingString.Move + SettingString.A6 : "";
// // agv.Msg = string.Format("{0} 在{1}已装载小料架,送往{2}", agv.Name, place, SettingString.A6);
// // Common.LogInfo(string.Format("{0} 在{1}已装载小料架,送往{2}", agv.Name, place, SettingString.A6));
// // return true;
// //}
//}
}
else if (shelfType.Equals(eShelfType.BigShelf))
{
int tarIdx = Common.nodeInfo.FindIndex(s => s.Name == SettingString.A5
&& (s.StateEquals(eNodeStatus.NeedC) || s.StateEquals(eNodeStatus.NeedEnter)) && s.IsUse);
if (tarIdx == -1)
{
Common.log.Debug(string.Format("{0} {1}不需要大料架", agv.Name, SettingString.A5));
}
else
{
nodeName = SettingString.A5;
Common.log.Debug(string.Format("{0} {1}需要大料架", agv.Name, SettingString.A5));
return true;
}
//tarIdx = Common.nodeInfo.FindIndex(s => s.Name == SettingString.A6 &&
//(s.StateEquals(eNodeStatus.NeedEnter) || s.StateEquals(eNodeStatus.NeedEnterLeave)) && s.IsUse);
//if (tarIdx == -1)
//{
// Common.LogInfo(string.Format("{0} {1}不需要大料架", agv.Name, SettingString.A6));
// //rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission[SettingString.MoveStandby]);
// //if (rtn)
// //{
// // agv.NextPlace = "";
// // agv.TaskSend = rtn ? SettingString.MoveStandby : "";
// // agv.Msg = string.Format("{0} 在{1}已装载大料架,送往{2}", agv.Name, place, SettingString.MoveStandby);
// // Common.LogInfo(string.Format("{0} 在{1}已装载大料架,送往{2}", agv.Name, place, SettingString.MoveStandby));
// //}
//}
//else
//{
// nodeName = SettingString.A6;
// Common.LogInfo(string.Format("{0} {1}需要大料架", agv.Name, SettingString.A6));
// return true;
// //rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission[SettingString.Move + SettingString.A6]);
// //if (rtn)
// //{
// // agv.NextPlace = "";
// // tarNodeName = SettingString.A6;
// // Common.nodeInfo[tarIdx].AgvName = agv.Name;
// // agv.TaskSend = rtn ? SettingString.Move + SettingString.A6 : "";
// // agv.Msg = string.Format("{0} 在{1}已装载大料架,送往{2}", agv.Name, place, SettingString.A6);
// // Common.LogInfo(string.Format("{0} 在{1}已装载大料架,送往{2}", agv.Name, place, SettingString.A6));
// // return true;
// //}
//}
}
return false;
}
/// <summary>
/// 查看A6料架的状况(A6主要用于Feeder)
/// </summary>
/// <param name="agv"></param>
/// <param name="node"></param>
public static bool CheckA6State(Agv_Info agv, eShelfType shelfType, out string nodeName)
{
bool rtn = false;
string place = agv.Place;
nodeName = "";
if (shelfType.Equals(eShelfType.SmallShelf))
{
//int tarIdx = Common.nodeInfo.FindIndex(s => s.Name == SettingString.A5 && s.ClientLevel.Equals(ClientLevel.High)
// && (s.StateEquals(eNodeStatus.NeedD) || s.StateEquals(eNodeStatus.NeedEnter)) && s.IsUse);
//if (tarIdx == -1)
//{
// Common.log.Debug(string.Format("{0} {1}不需要小料架", agv.Name, SettingString.A5));
//}
//else
//{
// nodeName = SettingString.A5;
// Common.log.Debug(string.Format("{0} {1}需要小料架", agv.Name, SettingString.A5));
// return true;
//}
int tarIdx = Common.nodeInfo.FindIndex(s => s.Name == SettingString.A6 &&
(s.StateEquals(eNodeStatus.NeedEnter) || s.StateEquals(eNodeStatus.NeedEnterLeave)) && s.IsUse);
if (tarIdx == -1)
{
Common.log.Debug(string.Format("{0} {1}不需要小料架", agv.Name, SettingString.A6));
//rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission[SettingString.MoveStandby]);
//if (rtn)
//{
// agv.NextPlace = "";
// agv.TaskSend = rtn ? SettingString.MoveStandby : "";
// agv.Msg = string.Format("{0} 在{1}已装载小料架,送往{2}", agv.Name, place, SettingString.MoveStandby);
// Common.LogInfo(string.Format("{0} 在{1}已装载小料架,送往{2}", agv.Name, place, SettingString.MoveStandby));
//}
}
else
{
nodeName = SettingString.A6;
Common.log.Debug(string.Format("{0} {1}需要小料架", agv.Name, SettingString.A6));
return true;
//rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission[SettingString.Move + SettingString.A6]);
//if (rtn)
//{
// agv.NextPlace = "";
// tarNodeName = SettingString.A6;
// Common.nodeInfo[tarIdx].AgvName = agv.Name;
// agv.TaskSend = rtn ? SettingString.Move + SettingString.A6 : "";
// agv.Msg = string.Format("{0} 在{1}已装载小料架,送往{2}", agv.Name, place, SettingString.A6);
// Common.LogInfo(string.Format("{0} 在{1}已装载小料架,送往{2}", agv.Name, place, SettingString.A6));
// return true;
//}
}
}
else if (shelfType.Equals(eShelfType.BigShelf))
{
//int tarIdx = Common.nodeInfo.FindIndex(s => s.Name == SettingString.A5
// && (s.StateEquals(eNodeStatus.NeedC) || s.StateEquals(eNodeStatus.NeedEnter)) && s.IsUse);
//if (tarIdx == -1)
//{
// Common.log.Debug(string.Format("{0} {1}不需要大料架", agv.Name, SettingString.A5));
//}
//else
//{
// nodeName = SettingString.A5;
// Common.log.Debug(string.Format("{0} {1}需要大料架", agv.Name, SettingString.A5));
// return true;
//}
int tarIdx = Common.nodeInfo.FindIndex(s => s.Name == SettingString.A6 &&
(s.StateEquals(eNodeStatus.NeedEnter) || s.StateEquals(eNodeStatus.NeedEnterLeave)) && s.IsUse);
if (tarIdx == -1)
{
Common.log.Debug(string.Format("{0} {1}不需要大料架", agv.Name, SettingString.A6));
//rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission[SettingString.MoveStandby]);
//if (rtn)
//{
// agv.NextPlace = "";
// agv.TaskSend = rtn ? SettingString.MoveStandby : "";
// agv.Msg = string.Format("{0} 在{1}已装载大料架,送往{2}", agv.Name, place, SettingString.MoveStandby);
// Common.LogInfo(string.Format("{0} 在{1}已装载大料架,送往{2}", agv.Name, place, SettingString.MoveStandby));
//}
}
else
{
nodeName = SettingString.A6;
Common.log.Debug(string.Format("{0} {1}需要大料架", agv.Name, SettingString.A6));
return true;
//rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission[SettingString.Move + SettingString.A6]);
//if (rtn)
//{
// agv.NextPlace = "";
// tarNodeName = SettingString.A6;
// Common.nodeInfo[tarIdx].AgvName = agv.Name;
// agv.TaskSend = rtn ? SettingString.Move + SettingString.A6 : "";
// agv.Msg = string.Format("{0} 在{1}已装载大料架,送往{2}", agv.Name, place, SettingString.A6);
// Common.LogInfo(string.Format("{0} 在{1}已装载大料架,送往{2}", agv.Name, place, SettingString.A6));
// return true;
//}
}
}
return false;
}
/// <summary>
/// 检查AGV是否有负载
/// </summary>
/// <returns></returns>
public static bool CheckLoad(Agv_Info agv)
{
return Common.mir.Add_Mission_Fleet(agv, Common.agvMission["CheckShelf"]);
}
public static bool DoorMission(Agv_Info agv, string doorName)
{
agv.Place = doorName;
return Common.mir.Add_Mission_Fleet(agv, Common.agvMission[SettingString.Move + doorName]);
}
/// <summary>
/// 检查当前任务是否结束
/// </summary>
/// <param name="taskName">任务名称</param>
/// <param name="taskGUID">任务GUID</param>
/// <returns></returns>
public static bool CheckTaskFinished(Agv_Info agv,string nodeName, string curTaskState)
{
log.Debug(agv.Name + " 检查当前任务是否结束: " +SettingString.Move + nodeName + " " + curTaskState);
return Common.agvMission[SettingString.Move+nodeName].Equals(agv.CurTaskGUID) && curTaskState.Equals(SettingString.Done);
}
/// <summary>
/// 检查充电任务是否分配完成
/// </summary>
/// <param name="taskName"></param>
/// <returns></returns>
public static bool CheckTaskFinished(Agv_Info agv, string taskName)
{
return taskName.Contains(SettingString.AutoCharge) && agv.CurTaskState.Equals(SettingString.Executing);
}
public static bool CheckEnterOrLeaveFinished(Agv_Info agv, string actionName, string curTaskState)
{
log.Debug(agv.Name + " 检查进出料是否结束: " + actionName + " " + curTaskState);
return Common.agvMission[actionName].Equals(agv.CurTaskGUID) && curTaskState.Equals(SettingString.Done);
}
//双层线工单信息
public static string doubleLine_WO = "";
/// <summary>
/// 查找空架任务
/// </summary>
/// <param name="curPlace">为空表示待机位</param>
/// <param name="nodeName">出空料架的节点名</param>
/// <param name="emptyAGVbACK">agv空车返回,带一个料架</param>
/// <returns></returns>
public static bool FindEmptyShelfNode(Agv_Info agv, out string nodeName, bool emptyAGVbACK = false)
{
nodeName = "";
if (!Common.CheckCanExecuteMission(agv))
return false;
int idx = nodeInfo.FindIndex(s => s.Name.Equals(SettingString.A6)
&& (s.StateEquals(eNodeStatus.NeedEnterLeave) || (s.StateEquals(eNodeStatus.NeedLeave))) && !s.RFID.Equals(""));
if (idx > -1)
{
if (AGVManager.FindFullShelfTarget(Common.nodeInfo[idx].RFID, out AGVManager.BoxDestInfo FullShelfDestInfo))
{
idx = nodeInfo.FindIndex(s => s.Name.Equals(FullShelfDestInfo.location) && s.EmptyShelfCnt > 0);
if (idx > -1)
{
if (FullShelfDestInfo.location.StartsWith(SettingString.C4_Name_Prefix) && SettingString.C4_AGV_IPs.Contains(agv.IP))
{
nodeName = FullShelfDestInfo.location;
Common.GetLineNameByNodeName(nodeName, out string line);
Common.LogInfo("A6出满料架的产线有空料架,优先处理 " + FullShelfDestInfo.ShowInfo(line));
return true;
}
else if (FullShelfDestInfo.location.StartsWith(SettingString.D4_Name_Prefix) && !SettingString.C4_AGV_IPs.Contains(agv.IP))
{
nodeName = FullShelfDestInfo.location;
Common.GetLineNameByNodeName(nodeName, out string line);
Common.LogInfo("A6出满料架的产线有空料架,优先处理 " + FullShelfDestInfo.ShowInfo(line));
return true;
}
}
}
else
{
if (FullShelfDestInfo != null)
{
Common.LogInfo("A6的出料信息不正确,请检查:" + FullShelfDestInfo.ShowInfo("ERROR"));
//return false;
}
}
}
//查询双层线正在出的工单料
if (AGVManager.FindCurSO(out AGVManager.WOData woData))
{
if (Common.GetNodeNameByLineName(woData.line, out string loc))
{
nodeName = loc;
doubleLine_WO = woData.ToTxt(loc);
Common.log.Debug(doubleLine_WO);
idx = nodeInfo.FindIndex(s => s.Name.Equals(loc) && s.EmptyShelfCnt > 0);
if (idx > -1)
{
if (loc.StartsWith(SettingString.C4_Name_Prefix) && SettingString.C4_AGV_IPs.Contains(agv.IP))
{
nodeName = loc;
Common.LogInfo("双层线正在出的工单目标产线有空料架,优先处4C-" + loc);
return true;
}
else if (loc.StartsWith(SettingString.D4_Name_Prefix) && !SettingString.C4_AGV_IPs.Contains(agv.IP))
{
nodeName = loc;
Common.LogInfo("双层线正在出的工单目标产线有空料架,优先处理4D-" + loc);
return true;
}
}
}
}
///AGV出满料带回一个料架
if (emptyAGVbACK)
{
//双层线是否需要小料架
if (CheckA5A6State(agv, eShelfType.SmallShelf, out string lineNodeName))
{
//if (curPlace.Equals(""))//待机位
// {
//4C车间寻找
if (SettingString.C4_AGV_IPs.Contains(agv.IP))
{
string nearNodeName = CalculateNearNode(agv, SettingString.C4_Name_Prefix);
if (nearNodeName.Equals(""))
{
return false;
}
nodeName = nearNodeName;
Common.log.Debug(agv.Name + " 双层线需要小料架,准备去4C-" + nearNodeName);
return true;
}
//4D车间寻找
if (!SettingString.C4_AGV_IPs.Contains(agv.IP))
{
string nearNodeName = CalculateNearNode(agv, SettingString.D4_Name_Prefix);
if (nearNodeName.Equals(""))
{
return false;
}
nodeName = nearNodeName;
Common.log.Debug(agv.Name + " 双层线需要小料架,准备去4D-" + nearNodeName);
return true;
}
}
}
else//主动拉料架
{
//双层线是否需要小料架
if (CheckA5State(agv, eShelfType.SmallShelf, out string lineNodeName2))
{
//if (curPlace.Equals(""))//待机位
// {
//4C车间寻找
if (SettingString.C4_AGV_IPs.Contains(agv.IP))
{
string nearNodeName = CalculateNearNode(agv, SettingString.C4_Name_Prefix);
if (!nearNodeName.Equals(""))
{
nodeName = nearNodeName;
Common.log.Debug(agv.Name + " 双层线需要小料架,准备去4C-" + nearNodeName);
return true;
}
}
//4D车间寻找
if (!SettingString.C4_AGV_IPs.Contains(agv.IP))
{
string nearNodeName = CalculateNearNode(agv, SettingString.D4_Name_Prefix);
if (!nearNodeName.Equals(""))
{
nodeName = nearNodeName;
Common.log.Debug(agv.Name + " 双层线需要小料架,准备去4D-" + nearNodeName);
return true;
}
}
}
else if (CheckA6State(agv, eShelfType.SmallShelf, out string lineNodeName1))
{
//4C车间寻找
if (SettingString.C4_AGV_IPs.Contains(agv.IP))
{
idx = nodeInfo.FindIndex(s => s.EmptyShelfCnt > 0 && s.Name.Equals(SettingString.C4FeederOut) && s.IsUse);
if (idx > -1)
{
int idx1 = agvInfo.FindIndex(s => s.CurJob is EnterLeaveShelfJob && ((EnterLeaveShelfJob)s.CurJob).LineName.Equals(SettingString.C4FeederOut));
if(idx1==-1)
{
nodeName = nodeInfo[idx].Name;
Common.log.Debug(agv.Name + " 双层线需要小料架,准备去4C-" + nodeName);
return true;
}
}
}
//4D车间寻找
if (!SettingString.C4_AGV_IPs.Contains(agv.IP))
{
idx = nodeInfo.FindIndex(s => s.EmptyShelfCnt > 0 && s.Name.Equals(SettingString.D4FeederOut) && s.IsUse);
if (idx > -1)
{
nodeName = nodeInfo[idx].Name;
Common.log.Debug(agv.Name + " 双层线需要小料架,准备去4D-" + nodeName);
return true;
}
}
}
}
return false;
}
/// <summary>
/// 查找出满料架任务
/// </summary>
/// <returns></returns>
public static bool FindFullShelfTask(Agv_Info agv)
{
if (!Common.CheckCanExecuteMission(agv))
return false;
int idx = nodeInfo.FindIndex(s => s.Name.Equals(SettingString.A6)
&& (s.StateEquals(eNodeStatus.NeedEnterLeave) || (s.StateEquals(eNodeStatus.NeedLeave))) && !s.RFID.Equals(""));
if (idx > -1)
{
if (AGVManager.FindFullShelfTarget(Common.nodeInfo[idx].RFID, out AGVManager.BoxDestInfo FullShelfDestInfo))
{
if (FullShelfDestInfo.location.StartsWith(SettingString.C4_Name_Prefix) && SettingString.C4_AGV_IPs.Contains(agv.IP))
{
int i = Common.agvInfo.FindIndex(s => s.CurJob is GoFullShelfStationJob && !s.IP.Equals(agv.IP));
if (i == -1)
return true;
}
else if (FullShelfDestInfo.location.StartsWith(SettingString.D4_Name_Prefix) && !SettingString.C4_AGV_IPs.Contains(agv.IP))
{
int i = Common.agvInfo.FindIndex(s => s.CurJob is SendFullShelfToLineJob && !s.IP.Equals(agv.IP)
&& ((SendFullShelfToLineJob)s.CurJob).FullShelfPlace.Equals(FullShelfDestInfo.location));
if (i > -1)
return false;
i = Common.agvInfo.FindIndex(s => s.CurJob is GoFullShelfStationJob && !s.IP.Equals(agv.IP));
if (i == -1)
return true;
}
}
else
{
if (FullShelfDestInfo != null)
{
Common.log.Error("A6的出料信息不正确,请检查:" + FullShelfDestInfo.ShowInfo("ERROR"));
}
}
}
return false;
}
/// <summary>
/// 查找当前出料工单的产线是否有空料架
/// </summary>
/// <param name="agv"></param>
/// <returns></returns>
public static bool FindEmptyShelfBeforeSendFullShelf(out string nodeName)
{
nodeName = "";
int idx = nodeInfo.FindIndex(s => s.Name.Equals(SettingString.A6)
&& (s.StateEquals(eNodeStatus.NeedEnterLeave) || (s.StateEquals(eNodeStatus.NeedLeave))) && !s.RFID.Equals("") && s.IsUse);
if (idx > -1)
{
if (AGVManager.FindFullShelfTarget(Common.nodeInfo[idx].RFID, out AGVManager.BoxDestInfo FullShelfDestInfo))
{
idx = nodeInfo.FindIndex(s => s.Name.Equals(FullShelfDestInfo.location) && s.EmptyShelfCnt > 0 && s.IsUse);
if (idx > -1)
{
nodeName = FullShelfDestInfo.location;
Common.GetLineNameByNodeName(nodeName, out string line);
Common.log.Debug("A6出满料架的产线有空料架,优先处理 " + FullShelfDestInfo.ShowInfo(line));
return true;
}
}
else
{
if (FullShelfDestInfo != null)
{
Common.log.Error("A6的出料信息不正确,请检查:" + FullShelfDestInfo.ShowInfo("ERROR"));
}
}
}
return false;
}
/// <summary>
/// 计算当前小车距离最近的任务点(只针对产线)
/// </summary>
/// <param name="agv"></param>
/// <returns>节点名称</returns>
public static string CalculateNearNode(Agv_Info agv, string RoomProfix)
{
double minDis = Double.MaxValue;
string nodeName = "";
List<ClientNode> clientNodes = nodeInfo.FindAll(s => s.EmptyShelfCnt > 0 && s.Name.Substring(0, 1).Equals(RoomProfix) && s.IsUse);
try
{
if (clientNodes.Count.Equals(0))
return nodeName;
foreach (var item in clientNodes)
{
double dis = Math.Sqrt(Math.Pow((agv.Position.x - item.position.X), 2) + Math.Pow((agv.Position.y - item.position.Y), 2));
Common.log.Debug(string.Format("{0} 距离{1}={2}", agv.Name, item.Name, dis.ToString("f2")));
if (dis < minDis)
{
minDis = dis;
nodeName = item.Name;
}
}
Common.log.Debug(string.Format("{0} 准备运动到产线 {1} 回收空料架", agv.Name, nodeName));
return nodeName;
}
catch (Exception e)
{
Common.log.Error("CalculateNearNode " + e.ToString());
}
return nodeName;
}
/// <summary>
/// 充电
/// </summary>
/// <param name="agv"></param>
/// <returns>充电任务结果</returns>
public static bool StatusCharge(Agv_Info agv, bool isRemovePreMission = false)
{
bool rtn;
string log;
agv.Place = "";
#region 指定充电位置
if (agv.IP == "10.85.199.72")//1764
{
rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission["AutoCharge4"], isRemovePreMission);
if (rtn)
{
//agv.TaskSend = "AutoCharge5";
agv.Place = SettingString.AutoCharge;
Common.chargeStatus.charge4 = agv.Name;
Common.chargeStatus.chargeInterval = DateTime.Now.Ticks;
log = string.Format("{0} AutoCharge4", agv.Name);
agv.Msg = log;
Common.LogInfo(log);
Common.mir.State_Ready(agv);
}
else
{
log = string.Format("{0} AutoCharge4 失败", agv.Name);
//防止上一个任务已执行但返回失败时,删除任务
//Common.mir.Del_Mission(agv);
Common.LogInfo(log);
}
return rtn;
}
else if (agv.IP == "10.85.199.73")//1767
{
rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission["AutoCharge5"], isRemovePreMission);
if (rtn)
{
//agv.TaskSend = "AutoCharge6";
agv.Place = SettingString.AutoCharge;
Common.chargeStatus.charge5 = agv.Name;
Common.chargeStatus.chargeInterval = DateTime.Now.Ticks;
log = string.Format("{0} AutoCharge5", agv.Name);
agv.Msg = log;
Common.LogInfo(log);
Common.mir.State_Ready(agv);
}
else
{
log = string.Format("{0} AutoCharge5 失败", agv.Name);
//防止上一个任务已执行但返回失败时,删除任务
//Common.mir.Del_Mission(agv);
Common.LogInfo(log);
}
return rtn;
}
//随机充电
if (Common.chargeStatus.charge3 == "")//1763 agv.IP == "10.85.199.71"
{
rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission["AutoCharge3"], isRemovePreMission);
if (rtn)
{
//agv.TaskSend = "AutoCharge3";
agv.Place = SettingString.AutoCharge;
Common.chargeStatus.charge3 = agv.Name;
Common.chargeStatus.chargeInterval = DateTime.Now.Ticks;
log = string.Format("{0} AutoCharge3", agv.Name);
agv.Msg = log;
Common.LogInfo(log);
Common.mir.State_Ready(agv);
}
else
{
log = string.Format("{0} AutoCharge3 失败", agv.Name);
//防止上一个任务已执行但返回失败时,删除任务
//Common.mir.Del_Mission(agv);
Common.LogInfo(log);
}
return rtn;
}
else if (Common.chargeStatus.charge6 == "")//1764 agv.IP == "10.85.199.72"
{
rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission["AutoCharge6"], isRemovePreMission);
if (rtn)
{
//agv.TaskSend = "AutoCharge4";
agv.Place = SettingString.AutoCharge;
Common.chargeStatus.charge6 = agv.Name;
Common.chargeStatus.chargeInterval = DateTime.Now.Ticks;
log = string.Format("{0} AutoCharge6", agv.Name);
agv.Msg = log;
Common.LogInfo(log);
Common.mir.State_Ready(agv);
}
else
{
log = string.Format("{0} AutoCharge6 失败", agv.Name);
//防止上一个任务已执行但返回失败时,删除任务
//Common.mir.Del_Mission(agv);
Common.LogInfo(log);
}
return rtn;
}
else
{
return false;
}
#endregion
}
/// <summary>
/// 判断电量是否够执行任务
/// </summary>
/// <param name="agv"></param>
/// <returns></returns>
public static bool CheckCanExecuteMission(Agv_Info agv)
{
if (agv.Battery <= Common.chargeStatus.chargeMin)
{
Common.log.Debug(agv.Name + " 电量小于20%,不执行任务");
return false;
}
return true;
}
/// <summary>
/// 判断小车是否空闲
/// </summary>
/// <param name="agv"></param>
/// <returns></returns>
public static bool CheckAGVStatusNone(Agv_Info agv)
{
if ((agv.CurJob is ChargeJob || agv.CurJob == null) && !agv.IsExistShelf)
return true;
else
return false;
}
public static void LogInfo(string text, bool isShow = true)
{
if (logTextBox == null) return;
if (logTextBox.InvokeRequired)
{
logTextBox.Invoke(new Action(() => LogInfo(text, isShow)));
return;
}
if (preLog.Equals(text))//连续重复的日志只打印一次
return;
preLog = text;
if (msg.Count > 255)
{
msg.RemoveRange(0, 10);
}
log.Info(text);
string tmpStr = "";
if (isShow)
{
msg.Add(string.Format("[{0}] {1}\r\n", DateTime.Now.ToString("HH:mm:ss"), text));
msg.ForEach(s => tmpStr += s);
logTextBox.Text = tmpStr;
//logTextBox.AppendText(string.Format("[{0}] {1}\r\n", DateTime.Now.ToString("HH:mm:ss"), text));
//logTextBox.ScrollToCaret();
}
}
public static void ReadLinePlace()
{
if (!System.IO.File.Exists(CONFIG_PATH + "LinePlace.txt"))
{
File.Create(CONFIG_PATH + "LinePlace.txt");
return;
}
string[] s = System.IO.File.ReadAllLines(CONFIG_PATH + "LinePlace.txt");
for (int i = 0; i < s.Count(); i++)
{
string[] mission = s[i].Split(',');
if (mission.Length != 2)
continue;
//missionManager.missionList.Add(new MissionStru(mission[0], mission[1]));
missionManager.AddMission(new MissionStru(mission[0], mission[1]));
}
}
/// <summary>
/// 添加空料架解绑
/// </summary>
/// <param name="nodeName"></param>
/// <returns></returns>
public static bool AddEmptyShelfTask(string nodeName)
{
int idx = Common.nodeInfo.FindIndex(s => s.Name == nodeName);
if (idx > -1)
{
// Common.missionManager.missionList.Add(new MissionStru(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), nodeName));
Common.missionManager.AddMission(new MissionStru(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), nodeName));
Common.nodeInfo[idx].IncreEmptyShelfCnt(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
using (System.IO.StreamWriter file = new System.IO.StreamWriter(CONFIG_PATH + "LinePlace.txt"))
{
foreach (var item in Common.missionManager.missionList)
{
file.WriteLine(string.Format("{0},{1}", item.CreateTime, item.NodeName));
}
}
return true;
}
else
{
log.Error("AddLinePlace 失败 节点" + nodeName + "不存在");
return false;
}
}
/// <summary>
/// 删除空架任务
/// </summary>
/// <param name="nodeName"></param>
/// <returns></returns>
public static bool DelEmptyShelfTask(string nodeName)
{
int idx = Common.nodeInfo.FindIndex(s => s.Name == nodeName);
if (idx > -1)
{
Common.nodeInfo[idx].DecreEmptyShelfCnt();
idx = Common.missionManager.missionList.FindIndex(s => s.NodeName == nodeName);
if (idx > -1)
{
LogInfo("删除一个空料架任务:" + nodeName);
Common.missionManager.DelMission(idx);
//Common.missionManager.missionList.RemoveAt(idx);
using (System.IO.StreamWriter file = new System.IO.StreamWriter(CONFIG_PATH + "LinePlace.txt"))
{
foreach (var item in Common.missionManager.missionList)
{
file.WriteLine(string.Format("{0},{1}", item.CreateTime, item.NodeName));
}
}
return true;
}
log.Error("DelLinePlace 失败 节点任务" + nodeName + "不存在");
return false;
}
else
{
log.Error("DelLinePlace 失败 节点" + nodeName + "不存在");
return false;
}
}
//public static void CheckAGVMissionState()
//{
// foreach (Agv_Info agv in agvInfo)
// {
// Thread.Sleep(50);
// bool rtn = Common.mir.Get_Register(agv, 20, out int regValue);
// if (rtn)
// {
// agv.GetPlace(regValue);
// Common.log.Debug(string.Format("软件开启:{0} Get_Register PLC{1}={2} Place={3} PlaceState={4}", agv.Name, 20, regValue, agv.Place, agv.PlaceState));
// if (!agv.Place.Equals(""))
// {
// int idx = nodeInfo.FindIndex(s => s.Name == agv.Place);
// if (idx > -1)
// {
// nodeInfo[idx].AgvName = agv.Name;
// }
// agv.TaskSend = "Move" + agv.Place;
// }
// }
// else
// {
// Common.log.Debug("CheckAGVMissionState 获取PLC20失败");
// }
// }
//}
public static void GetNodesPosition()
{
Agv_Info agv = agvInfo[0];
foreach (ClientNode clientNode in nodeInfo)
{
bool rtn = Common.mir.Get_Node_Pos(agv, clientNode, out MirPosition mirPosition);
Thread.Sleep(50);
if (rtn)
{
clientNode.position.X = mirPosition.pos_x;
clientNode.position.Y = mirPosition.pos_y;
Common.log.Debug(string.Format("软件开启:{0} 获取节点位置({1},{2})", clientNode.Name, clientNode.position.X, clientNode.position.Y));
}
else
{
Common.log.Error(clientNode.Name+ " GetNodesPosition 获取节点位置失败");
}
}
}
/// <summary>
/// 检查该目的地是否有车占用
/// </summary>
/// <param name="nodeName"></param>
/// <returns>false:未被占用</returns>
public static bool Check4CTarget(Agv_Info agv, string nodeName)
{
List<Agv_Info> agvs = agvInfo.FindAll(s => !s.IP.Equals(agv.IP) && (s.CurJob is GoEmptyShelfLineJob || s.CurJob is SendFullShelfToLineJob)
); //&& !s.Name.Equals(StandbyStation.C4_Station1) && !s.Name.Equals(StandbyStation.C4_Station2)
if (agvs.Count.Equals(0))
return false;
else if (agvs.Count > 0)
{
foreach (Agv_Info item in agvs)
{
if (item.CurJob is GoEmptyShelfLineJob)
{
if (((GoEmptyShelfLineJob)item.CurJob).EmptyShelfPlace.Equals(nodeName) && item.CurTaskName.Equals(SettingString.Move + nodeName))
{
log.Debug(item.Name + " 在目的地:" + ((GoEmptyShelfLineJob)item.CurJob).EmptyShelfPlace + " " + agv.Name + "暂不去" + nodeName);
return true;
}
}
else if (item.CurJob is SendFullShelfToLineJob)
{
if (((SendFullShelfToLineJob)item.CurJob).FullShelfPlace.Equals(nodeName) && item.CurTaskName.Equals(SettingString.Move + nodeName))
{
log.Debug(item.Name + " 在目的地:" + ((SendFullShelfToLineJob)item.CurJob).FullShelfPlace + " " + agv.Name + "暂不去" + nodeName);
return true;
}
}
}
}
return false;
}
/// <summary>
/// 移动到4C待机位
/// </summary>
/// <param name="agv"></param>
public static void MoveTo4CStandy(Agv_Info agv)
{
if (StandbyStation.C4_Station1.Equals(""))
{
StandbyStation.C4_Station1 = agv.Name;
Common.MoveToNode(agv, SettingString.C4_STANDBY1);
}
else if (StandbyStation.C4_Station2.Equals(""))
{
StandbyStation.C4_Station2 = agv.Name;
Common.MoveToNode(agv, SettingString.C4_STANDBY2);
}
}
/// <summary>
/// 清除该小车在待机位的信息
/// </summary>
public static void DeleteStandyInfo(Agv_Info agv)
{
if (StandbyStation.C4_Station1.Equals(agv.Name))
{
StandbyStation.C4_Station1 = "";
}
else if (StandbyStation.C4_Station2.Equals(agv.Name))
{
StandbyStation.C4_Station2 = "";
}
}
/// <summary>
/// 获取Job任务状态
/// </summary>
/// <param name="CurTaskID"></param>
/// <returns></returns>
public static string GetTakJobState(int CurTaskID)
{
if (!CurTaskID.Equals(-1) && Common.mir.Get_Task_State(CurTaskID, out string st))
return st;
return SettingString.Wait;
}
}
public static class API
{
[DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)]
public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
[DllImport("user32.dll ", SetLastError = true)]
public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);
public const int SW_RESTORE = 9;
}
/// <summary>
/// 客户端
/// </summary>
public class Client
{
/// <summary>
/// 循环
/// </summary>
public bool Loop;
/// <summary>
/// IP地址
/// </summary>
public string IP;
/// <summary>
/// 是否连接
/// </summary>
public bool IsConn;
/// <summary>
/// 节点名称集合
/// </summary>
public List<string> nodeName;
/// <summary>
/// 套接字
/// </summary>
public Socket Socket;
/// <summary>
/// 接收数据线程
/// </summary>
public Thread ListenNet;
}
/// <summary>
/// 地点状态
/// </summary>
public enum ePlaceState
{
/// <summary>
/// 没有任务
/// </summary>
None = 0,
/// <summary>
/// 小车移动任务
/// </summary>
Move = 1,
/// <summary>
/// 小车移动任务完成
/// </summary>
MoveFinish = 2,
/// <summary>
/// 小车Enter任务
/// </summary>
Enter = 3,
/// <summary>
/// 小车Enter任务完成
/// </summary>
EnterFinish = 4,
/// <summary>
/// 小车Leave任务
/// </summary>
Leave = 5,
/// <summary>
/// 小车Leave任务完成
/// </summary>
LeaveFinish = 6,
/// <summary>
/// 出错
/// </summary>
Error = 9
}
public struct PositionStru
{
public double X;
public double Y;
}
public class ChargeStatus
{
/// <summary>
/// 1号充电桩的AGV名称
/// </summary>
public string charge3 = "";
/// <summary>
/// 1号充电桩的AGV名称
/// </summary>
public string charge4 = "";
/// <summary>
/// 1号充电桩的AGV名称
/// </summary>
public string charge5 = "";
/// <summary>
/// 1号充电桩的AGV名称
/// </summary>
public string charge6 = "";
/// <summary>
/// 1号充电桩的AGV名称
/// </summary>
public string charge7 = "";
/// <summary>
/// 充电等待时间(s)
/// </summary>
public int chargeWait = 0;
/// <summary>
/// 充电最大电量,小于该值等待指定时间去充电
/// </summary>
public int chargeMax;
/// <summary>
/// 充电最小电量,小于该值直接去充电
/// </summary>
public int chargeMin;
/// <summary>
/// 两车充电间隔时间(ms)
/// </summary>
public long chargeInterval;
private bool _autoCharge;
public bool AutoCharge
{
set
{
_autoCharge = value;
Common.appConfig.AppSettings.Settings["AutoCharge"].Value = value.ToString();
Common.appConfig.Save();
}
get
{
return _autoCharge;
}
}
public ChargeStatus()
{
_autoCharge = Convert.ToBoolean(Common.appConfig.AppSettings.Settings["AutoCharge"].Value);
chargeWait = Convert.ToInt32(Common.appConfig.AppSettings.Settings["ChargeWait"].Value);
string s = Common.appConfig.AppSettings.Settings["ChargeThreshold"].Value;
string[] arr = s.Split(',');
chargeMin = Convert.ToInt32(arr[0]);
chargeMax = Convert.ToInt32(arr[1]);
chargeInterval = 0;
}
public void ClearRandomChargeInfo(Agv_Info agv)
{
if (Common.chargeStatus.charge3.Equals(agv.Name))
{
Common.chargeStatus.charge3 = "";
}
if (Common.chargeStatus.charge6.Equals(agv.Name))
{
Common.chargeStatus.charge6 = "";
}
}
}
/// <summary>
/// 4C待机位
/// </summary>
public struct StandbyStation
{
public string C4_Station1;
public string C4_Station2;
}
/// <summary>
/// 任务信息结构
/// </summary>
public struct MissionStru
{
public string NodeName;
public string CreateTime;
/// <summary>
/// 任务结构
/// </summary>
/// <param name="dateTime">创建时间</param>
/// <param name="name">节点名称</param>
public MissionStru(string dateTime, string name)
{
NodeName = name;
CreateTime = dateTime;
}
}
/// <summary>
/// 任务管理
/// </summary>
public class MissionManager
{
public delegate void MissionChangedHandler();
public event MissionChangedHandler MissionChanged;
/// <summary>
/// 任务列表
/// </summary>
public List<MissionStru> missionList;
/// <summary>
/// 空料架解绑总数
/// </summary>
public Int32 EmptyMissionCount
{
get { return missionList.Count; }
}
public void AddMission(MissionStru missionStru)
{
missionList.Add(missionStru);
MissionChanged?.Invoke();
}
public void DelMission(int idx)
{
if (idx == -1)
return;
Common.missionManager.missionList.RemoveAt(idx);
MissionChanged?.Invoke();
}
public MissionManager()
{
missionList = new List<MissionStru>();
}
}
}
\ No newline at end of file \ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Threading;
using System.Xml;
using System.Windows.Forms;
using AGVControl;
namespace BLL
{
public class ConfigAppSettings
{
public static string GetValue(string key)
{
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if (config.AppSettings.Settings[key] == null)
{
Common.LogInfo("未找到配置:" + key + ",请检查配置是否完整!");
return "";
}
else
{
return config.AppSettings.Settings[key].Value;
}
}
public static decimal GetNumValue(string key)
{
decimal a = 0;
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if (config.AppSettings.Settings[key] == null)
{
Common.log.Error("未找到配置:" + key + ",请检查配置是否完整!");
return a;
}
else
{
{
Decimal.TryParse(config.AppSettings.Settings[key].Value, out a);
}
}
return a;
}
public static int GetIntValue(string key)
{
int a = 0;
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if (config.AppSettings.Settings[key] == null)
{
Common.log.Info("未找到配置:" + key + ",请检查配置是否完整!");
return a;
}
else
{
{
Int32.TryParse(config.AppSettings.Settings[key].Value, out a);
}
} return a;
}
public static void SaveValue(string key, int value)
{
SaveValue(key, value.ToString());
}
public static void SaveValue(string key, string value)
{
try
{
if (key.Equals("") || value.Equals(""))
{
return;
}
//增加的内容写在appSettings段下 <add key="RegCode" value="0"/>
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if (config.AppSettings.Settings[key] == null)
{
SetValue(key, value);
}
else
{
UpdateConfig(key, value);
}
}
catch (Exception ex)
{
Common.log.Error( "SaveValue保存配置出错:AppKey=" + key + ",AppValue=" + value + "," + ex.StackTrace);
}
}
/// <summary>
/// 更新配置文件信息
/// </summary>
/// <param name="name">配置文件字段名称</param>
/// <param name="Xvalue">值</param>
private static void UpdateConfig(string name, string Xvalue)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(Application.ExecutablePath + ".config");
XmlNode node = doc.SelectSingleNode(@"//add[@key='" + name + "']");
XmlElement ele = (XmlElement)node;
ele.SetAttribute("value", Xvalue);
doc.Save(Application.ExecutablePath + ".config");
}
catch (Exception ex)
{
Common.log.Error( "UpdateConfig保存配置出错:name=" + name + ",Xvalue=" + Xvalue + "," + ex.StackTrace);
}
}
///<summary>
///向.config文件的appKey结写入信息AppValue 保存设置
///</summary>
///<param name="AppKey">节点名</param>
///<param name="AppValue">值</param>
private static void SetValue(String AppKey, String AppValue)
{
try
{
XmlDocument xDoc = new XmlDocument();
xDoc.Load(System.Windows.Forms.Application.ExecutablePath + ".config");
XmlNode xNode;
XmlElement xElem1;
XmlElement xElem2;
xNode = xDoc.SelectSingleNode("//appSettings");
xElem1 = (XmlElement)xNode.SelectSingleNode("//add[@key='" + AppKey + "']");
if (xElem1 != null)
xElem1.SetAttribute("value", AppValue);
else
{
xElem2 = xDoc.CreateElement("add");
xElem2.SetAttribute("key", AppKey);
xElem2.SetAttribute("value", AppValue);
xNode.AppendChild(xElem2);
}
xDoc.Save(System.Windows.Forms.Application.ExecutablePath + ".config");
}
catch (Exception ex)
{
Common.log.Error( "SetValue保存配置出错:AppKey=" + AppKey + ",AppValue=" + AppValue + "," + ex.StackTrace);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Drawing.Text;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using AGVControl;
using log4net.Util;
using RestSharp;
namespace BLL
{
public class Control
{
//private int areaC_Index;
private System.Timers.Timer AgvCallTimer;
private System.Timers.Timer AgvStateTimer;
//public List<string> Marks;
private const int REG_STATUS = 20;
//private List<string> shelfLockedNodeNames;
public delegate void AgvChangedEvent(int agvIndex);
public delegate void AgvMissionEvent();
public event AgvChangedEvent AgvChanged;
public event AgvChangedEvent AgvOnline;
public Control()
{
AgvCallTimer = new System.Timers.Timer
{
Interval = 300,
AutoReset = true,
Enabled = false
};
AgvCallTimer.Elapsed += AgvCallTimer_Elapsed;
AgvStateTimer = new System.Timers.Timer
{
Interval = 1500,
AutoReset = true,
Enabled = false
};
AgvStateTimer.Elapsed += AgvStateTimer_Elapsed;
}
public void Start()
{
AgvCallTimer.Enabled = true;
AgvStateTimer.Enabled = true;
AgvCallTimer.Start();
AgvStateTimer.Start();
}
public void Stop()
{
AgvCallTimer.Enabled = false;
AgvStateTimer.Enabled = false;
AgvCallTimer.Stop();
AgvStateTimer.Stop();
}
private bool AgvStateInProcess = false;
private eAGVState preAGVState = eAGVState.None;
private void AgvStateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
bool rtn;
if (AgvStateInProcess) return;
AgvStateInProcess = true;
List<AlarmMsg> msglist = new List<AlarmMsg>();
for (int j = 0; j < Common.nodeInfo.Count; j++)
{
if (!Common.nodeInfo[j].Online)
{
msglist.Add(new AlarmMsg(Common.nodeInfo[j].AliceName, "lineAgv." + Common.nodeInfo[j].Name + ".OffLine", "离线"));
}
}
BLL.AGVManager.updateDeviceAlarmMsg(msglist);
for (int i = 0; i < Common.agvInfo.Count; i++)
{
//上报异常
bool isAlarm = false;
if (msglist.Count > 0)
msglist.Clear();
try
{
if (!CheckOnline(i)) continue;
bool change = false;
Common.mir.Get_Task_State(Common.agvInfo[i].CurTaskID, out string stateStr);
Thread.Sleep(50);
//获取AGV状态
rtn = Common.mir.Get_State(Common.agvInfo[i], out eAGVState stateID, out string stateText, out int battery, out string mission_text, out Agv_Info.clsPosition position);
Thread.Sleep(50);
if (rtn) change = Common.agvInfo[i].SetState(stateID, stateStr, battery, mission_text, position);
//更新状态stateID.Equals(eAGVState.Executing)
if (change)
{
AgvChanged?.Invoke(i);
}
Common.log.Debug("获取AGV状态");
Thread.Sleep(50);
rtn = Common.mir.Get_IO_Status(Common.agvInfo[i], out bool[] input, out bool[] output);
Common.log.Debug("获取IO状态");
preAGVState = Common.agvInfo[i].StateID;
if (Common.agvInfo[i].StandTimeOut)
{
isAlarm = true;
msglist.Add(new AlarmMsg(Common.agvInfo[i].Name, "lineAgv." + Common.agvInfo[i].Name + ".StandTimeOut", "在" + Common.agvInfo[i].PlaceAliceName + "停留超时" + (DateTime.Now - Common.agvInfo[i].StandStartTime).TotalMinutes.ToString("f2") + "分钟"));
}
if (stateText.Equals("Error") || stateText.Equals("EmergencyStop") || stateText.Equals("Pause"))
{
isAlarm = true;
msglist.Add(new AlarmMsg(Common.agvInfo[i].Name, "lineAgv." + Common.agvInfo[i].Name + ".Error.EmergencyStop", "agv状态:" + stateText + ""));
}
if (!isAlarm)
{
try
{
if (!Common.agvInfo[i].Msg.Equals(""))
msglist.Add(new AlarmMsg(Common.agvInfo[i].Name, "lineAgv." + Common.agvInfo[i].Name + ".Msg", Common.agvInfo[i].Msg, 1));
else
{
if ((Common.agvInfo[i].Place.Contains(SettingString.AutoCharge) || Common.agvInfo[i].Place.Contains(SettingString.Standby)))
{
msglist.Add(new AlarmMsg(Common.agvInfo[i].Name, "lineAgv." + Common.agvInfo[i].Name + ".Place", Common.agvInfo[i].Place, 1));
}
}
}
catch (Exception ex)
{
Common.log.Error(Common.agvInfo[i].Name + "上报小车运行步骤失败" + ex.Message + ex.StackTrace);
}
}
BLL.AGVManager.updateDeviceAlarmMsg(msglist);
}
catch (Exception ex)
{
Common.log.Error("AgvStateTimer_" + Common.agvInfo[i].Name + ex.Message + ex.StackTrace);
}
}
AgvStateInProcess = false;
}
/// <summary>
/// 从节点获取任务
/// </summary>
/// <param name="agv_Info"></param>
/// <returns></returns>
public Job GetJob(Agv_Info agv_Info)
{
foreach (Node node in Common.nodeInfo)
{
Job job = null;
if (node.Name.Equals("A5"))
{
if (!SettingString.C4_AGV_IPs.Contains(agv_Info.IP))
continue;
job = ((DoubleLineNodeFor4C)node).GetNewJob(agv_Info);
}
else if (node.Name.Equals("A6"))
{
if (SettingString.C4_AGV_IPs.Contains(agv_Info.IP))
continue;
job = ((DoubleLineNodeFor4D)node).GetNewJob(agv_Info);
}
else
{
job = node.GetNewJob(agv_Info);
}
if (job != null)
{
Common.log.Info(node.Name + " GetJob OK " + job.ToString());
return job;
}
}
return null;
}
private bool AgvCallInProcess = false;
private void AgvCallTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (AgvCallInProcess) return;
AgvCallInProcess = true;
for (int i = 0; i < Common.agvInfo.Count; i++)
{
try
{
Agv_Info agv = Common.agvInfo[i];
if (!agv.IsCon) continue; //AGV网络连接
if (!Common.agvInfo[i].IsUse) continue; //AGV是否可用
//Ready,Pause,Executing,Error
if (!Common.agvInfo[i].StateID.Equals(eAGVState.Ready) && !Common.agvInfo[i].StateID.Equals(eAGVState.Pause)
&& !Common.agvInfo[i].StateID.Equals(eAGVState.Executing) && !Common.agvInfo[i].StateID.Equals(eAGVState.Error))
{
Common.LogInfo(string.Format("{0}不能调用 StateID={1}", Common.agvInfo[i].Name, Common.agvInfo[i].StateID.ToString()));
continue;
}
if (agv.CurJob == null)
{
Job job = GetJob(agv);
if (job != null)
{
agv.CurJob = job;
}
else
{
//if (agv.Battery < Common.chargeStatus.chargeMax)
agv.CurJob = new ChargeJob(agv.Place);
}
}
if (agv.CurJob != null)
{
agv.CurJob = agv.CurJob.Execute(agv);
}
}
catch (Exception ex)
{
Common.log.Error("AgvCall " + ex.Message + ex.StackTrace);
}
}
AgvCallInProcess = false;
}
private bool CheckOnline(int idx)
{
bool rtn = Common.mir.CheckIP(Common.agvInfo[idx].IP);
if (rtn)
{
if (Common.agvInfo[idx].IsCon)
{
Common.log.Debug(Common.agvInfo[idx].Name + " Online");
}
else
{
Common.agvInfo[idx].IsCon = true;
Common.LogInfo(Common.agvInfo[idx].Name + " Online");
AgvOnline?.Invoke(idx);
AgvChanged?.Invoke(idx);
}
}
else
{
if (Common.agvInfo[idx].IsCon)
{
Common.agvInfo[idx].IsCon = false;
Common.LogInfo(Common.agvInfo[idx].Name + " Offline");
AgvOnline?.Invoke(idx);
AgvChanged?.Invoke(idx);
}
else
{
Common.log.Debug(Common.agvInfo[idx].Name + " Offline");
}
}
return rtn;
}
}
}
\ No newline at end of file \ No newline at end of file
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Collections;
using System.Net;
using System.Net.Security;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Reflection;
using System.Net.NetworkInformation;
using BLL;
using AGVControl;
namespace BLL
{
public class HttpHelper
{
// public static readonly ILog LOGGER = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public static string Post(string url, string paramData)
{
return Post(url, paramData, Encoding.UTF8);
}
//public static bool PingURLIP(string url, int ms=100)
//{
// string[] urlArray = url.Split('/');
// if (urlArray.Length > 3)
// {
// string ip = urlArray[2];
// Ping pingSender = new Ping();
// PingReply reply = pingSender.Send(ip, ms);//第一个参数为ip地址,第二个参数为ping的时间
// if (reply.Status == IPStatus.Success)
// {
// //通
// return true;
// }
// else
// {
// //不通
// return false;
// }
// }
// return true;
//}
/// <summary>
///
/// </summary>
/// <param name="url"></param>
/// <param name="operation"></param>
/// <param name="simulate">是否模拟服务器返回结果</param>
/// <returns></returns>
//public static Operation Post(string url, Operation operation, bool simulate)
//{
// try
// {
// ////如果Op=0或者Op=5,先拼Ip,不通不发送
// //if (operation.op < 0 || operation.op.Equals(5))
// //{
// // if (PingURLIP(url, 100).Equals(false))
// // {
// // return null;
// // }
// //}
// if (simulate)
// {//模拟服务器返回
// operation.status = 200;
// operation.data.Clear();
// operation.data.Add("posId", "A001");
// string pos = "D100-111#D102-222#D104-333";
// operation.data.Add("pos", pos);
// if (operation.op == 1 || operation.op == 2)
// {//入库或出库
// string json = JsonHelper.SerializeObject(operation);
// LogUtil.error("模拟HTTP服务器返回出库入库信息:" + json);
// return operation;
// }
// }
// else
// {
// string json = "";
// try
// {
// json = JsonHelper.SerializeObject(operation);
// }
// catch (Exception ex)
// {
// LogUtil.error("JsonHelper.SerializeObject(operation) 出错【operation.op=" + operation.op + "】" + ex);
// }
// string result = Post(url, json);
// if (!string.IsNullOrEmpty(result))
// {
// try
// {
// return JsonHelper.DeserializeJsonToObject<Operation>(result);
// }
// catch (Exception ex)
// {
// LogUtil.error("JsonHelper.DeserializeJsonToObject 出错【result=" + result + "】" + ex);
// }
// }
// }
// }
// catch (Exception ex)
// {
// LogUtil.error("Post 出错【operation.op=" + operation.op + "】:" + ex);
// }
// return null;
//}
public static string LastServerMsg = "";
public static string Post(string url, string paramData, Encoding encoding)
{
//if (PingURLIP(url, 100).Equals(false))
//{
// return null;
//}
if (paramData != "null" && paramData != null)
{
// LogUtil.debug(LOGGER, "HTTP POST to " + url + " \n\t >> " + paramData);
}
string result = "";
if (url.ToLower().IndexOf("https", System.StringComparison.Ordinal) > -1)
{
ServicePointManager.ServerCertificateValidationCallback =
new RemoteCertificateValidationCallback((sender, certificate, chain, errors) => { return true; });
}
try
{
var wc = new MyWebClient(5000);
if (string.IsNullOrEmpty(wc.Headers["Content-Type"]))
wc.Headers.Add("Content-Type", "application/json;charset=UTF-8");
wc.Encoding = encoding;
result = wc.UploadString(url, "POST", paramData);
//Common.LogInfo(result);
}
catch (Exception e)
{
Common.log.Error("POST ERROR:" + e.ToString());
}
if (!result.Contains("null") && result.Length != 0)
{
//LogUtil.debug(LOGGER,"receive << " + result);
}
LastServerMsg = DateTime.Now.ToLongTimeString() + " URL:" + url + "\r\n"
+ "发送:" + paramData + "\r\n"
+ "接收:" + result + "\r\n"
;
return result;
}
public static string Get(string url)
{
return Get(url, Encoding.UTF8);
}
public static string Get(string url, Encoding encoding)
{
try
{
Common.log.Debug("HTTP GET FROM: " + url);
var wc = new WebClient { Encoding = encoding };
var readStream = wc.OpenRead(url);
using (var sr = new StreamReader(readStream, encoding))
{
var result = sr.ReadToEnd();
Common.log.Debug("receive << " + result);
return result;
}
}
catch (Exception e)
{
Common.log.Error("HTTP GET ERROR:" + e.Message);
}
return "";
}
}
}
\ No newline at end of file \ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace AGVControl
{
class IniHelper
{
[DllImport("kernel32")]
//section:要读取的段落名
//key: 要读取的键点击打开链接点击打开链接
//defVal: 读取异常的情况下的缺省值
//retVal: key所对应的值,如果该key不存在则返回空值
//size: 值允许的大小
//filePath: INI文件的完整路径和文件名
private static extern int GetPrivateProfileString(string section, string key, string defVal, StringBuilder retVal, int size, string filePath);
[DllImport("kernel32")]
//section: 要写入的段落名
//key: 要写入的键,如果该key存在则覆盖写入
//val: key所对应的值
//filePath: INI文件的完整路径和文件名
private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
/// <summary>
/// 读取INI文件
/// </summary>
/// <param name="section">项目名称(如 [section] )</param>
/// <param name="skey">键</param>
/// <param name="path">路径</param>
public static string ReadValue(string section, string skey, string path)
{
StringBuilder temp = new StringBuilder(500);
GetPrivateProfileString(section, skey, "", temp, 500, path);
return temp.ToString();
}
/// <summary>
/// 写入ini文件
/// </summary>
/// <param name="section">项目名称</param>
/// <param name="key">键</param>
/// <param name="value">值</param>
/// <param name="path">路径</param>
public static void WriteValue(string section, string key, string value, string path)
{
WritePrivateProfileString(section, key, value, path);
}
}
}
using AGVControl;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
namespace BLL
{
/// <summary>
/// Json帮助类
/// </summary>
public class JsonHelper
{
/// <summary>
/// 将对象序列化为JSON格式
/// </summary>
/// <param name="o">对象</param>
/// <returns>json字符串</returns>
public static string SerializeObject(object o)
{
string json = JsonConvert.SerializeObject(o);
return json;
}
/// <summary>
/// 解析JSON字符串生成对象实体
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="json">json字符串(eg.{"ID":"112","Name":"石子儿"})</param>
/// <returns>对象实体</returns>
public static T DeserializeJsonToObject<T>(string json) where T : class
{
JsonSerializer serializer = new JsonSerializer();
StringReader sr = new StringReader(json);
object o = serializer.Deserialize(new JsonTextReader(sr), typeof(T));
T t = o as T;
return t;
}
/// <summary>
/// 解析JSON数组生成对象实体集合
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="json">json数组字符串(eg.[{"ID":"112","Name":"石子儿"}])</param>
/// <returns>对象实体集合</returns>
public static List<T> DeserializeJsonToList<T>(string json) where T : class
{
JsonSerializer serializer = new JsonSerializer();
StringReader sr = new StringReader(json);
object o = serializer.Deserialize(new JsonTextReader(sr), typeof(List<T>));
List<T> list = o as List<T>;
return list;
}
/// <summary>
/// 反序列化JSON到给定的匿名对象.
/// </summary>
/// <typeparam name="T">匿名对象类型</typeparam>
/// <param name="json">json字符串</param>
/// <param name="anonymousTypeObject">匿名对象</param>
/// <returns>匿名对象</returns>
public static T DeserializeAnonymousType<T>(string json, T anonymousTypeObject)
{
T t = JsonConvert.DeserializeAnonymousType(json, anonymousTypeObject);
return t;
}
/// <summary>
///写入JSON文件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="ts"></param>
/// <param name="fileName"></param>
public static void WriteJson<T>(List<T> ts, string fileName) where T : class
{
try
{
string path = Common.CONFIG_PATH + fileName + ".json";
string output = JsonConvert.SerializeObject(ts,Formatting.Indented);
File.WriteAllText(path, output);
}
catch (Exception e)
{
Common.log.Error(e.Message + "/r/n" + e.StackTrace);
}
}
/// <summary>
/// 读取JSON文件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="ts"></param>
/// <param name="fileName"></param>
public static List<T> ReadJson<T>(string fileName) where T : class
{
try
{
string path = Common.CONFIG_PATH + fileName + ".json";
StreamReader streamReader = new StreamReader(path);
string jsonStr = streamReader.ReadToEnd();
List<T> jsonObj = DeserializeJsonToList<T>(jsonStr);
streamReader.Close();
return jsonObj;
}
catch (Exception e)
{
Common.log.Error(e.Message + "/r/n" + e.StackTrace);
return null;
}
}
}
///// <summary>
///// 与服务器通信用对象
///// </summary>
//public class Operation
//{
// private string _cid = "";
// public string cid
// {
// get { return _cid; }
// set { _cid = value; }
// }
// public int seq { get; set; }
// public int op { get; set; }
// public int status { get; set; }
// private string _error = "";
// public string error
// {
// get { return _error; }
// set { _error = value; }
// }
// private Dictionary<string, string> _data = new Dictionary<string,string>();
// public Dictionary<string, string> data {
// get { return _data; }
// set { _data = value; }
// }
//}
}
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Runtime.Serialization;
using System.ServiceModel.Activation;
using System;
using AGVControl;
using System.IO;
using System.Xml;
using System.Text;
namespace BLL
{
[ServiceContract(Name = "Services")]
internal interface IWebService
{
[OperationContract]
[WebInvoke(UriTemplate = "CreateEmptyRecycleTask", Method = "POST", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Xml)]
string CreateEmptyRecycleTask(Stream stream);//string line
//?emptyStation={line}
[OperationContract]
[WebInvoke(UriTemplate = "CreateEmptyRecycleTask?emptyStation={line}&rfid={RFID}", Method = "GET", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Xml)]
string CreateEmptyRecycleTaskGET(string line,string RFID="");
}
[DataContract]
internal class Result
{
[DataMember]
public bool Succeed { get; set; }
[DataMember]
public string ResultData { get; set; }
[DataMember]
public string ErrorMessage { get; set; }
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single, IncludeExceptionDetailInFaults = true)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
internal class ClsWebService : IWebService
{
static log4net.ILog Log = log4net.LogManager.GetLogger("LineWebService");
internal ClsWebService()
{
}
public string CreateEmptyRecycleTask(Stream stream)
{
Result res;
StreamReader sr = new StreamReader(stream);
string s = sr.ReadToEnd();
System.Collections.Specialized.NameValueCollection nvc = System.Web.HttpUtility.ParseQueryString(s);
string emptyStation = nvc["emptyStation"];
string rfid = nvc["rfid"];
if (emptyStation == null)
res = new Result() { Succeed = false, ResultData = null, ErrorMessage = "emptyStation =null " };
else
{
if (emptyStation.Equals("Feeder"))
{
emptyStation = "FeederOut";
}
else if (emptyStation.Equals("4CFeeder"))
{
emptyStation = "4CFeederOut";
}
if (Common.GetNodeNameByLineName(emptyStation, out string value))
{
if (!Common.AddEmptyShelfTask(value))
{
Common.log.Error("CreateEmptyRecycleTask(POST) 节点[" + value + "]不存在");
res = new Result() { Succeed = false, ResultData = null, ErrorMessage = "CreateEmptyRecycleTask failed: " + emptyStation };
}
else
{
if (rfid == null)
{
res = new Result() { Succeed = true, ResultData = null, ErrorMessage = "" };
Log.Info(string.Format("WebService Request(POST) emptyStation={0},rfid=null", emptyStation));
Common.LogInfo("任务[POST]:" + value + " 出空料架 [" + emptyStation + "]");
}
else
{
res = new Result() { Succeed = true, ResultData = rfid, ErrorMessage = "" };
Log.Info(string.Format("WebService Request(POST) emptyStation={0},rfid={1}", emptyStation, rfid));
Common.LogInfo("任务[POST]:" + value + " 出空料架 [location=" + emptyStation + ",rfid=" + rfid + "]");
}
}
// AGVControl.Common.log.Debug("WebService POST Response OK");
}
else
{
res = new Result() { Succeed = false, ResultData = null, ErrorMessage = "Not find " + emptyStation };
AGVControl.Common.log.Error("WebService POST Response false " + "Not find " + emptyStation);
}
}
return JsonHelper.SerializeObject(res);
}
public string CreateEmptyRecycleTaskGET(string line,string RFID)
{
Result res;
if (line.Equals("Feeder"))
{
line = "FeederOut";
}
else if (line.Equals("4CFeeder"))
{
line = "4CFeederOut";
}
if (Common.GetNodeNameByLineName(line, out string value))
{
if (!Common.AddEmptyShelfTask(value))
{
Common.log.Error("CreateEmptyRecycleTask 节点[" + value + "]不存在");
res = new Result() { Succeed = false, ResultData = null, ErrorMessage = "CreateEmptyRecycleTask failed: " + line };
}
else
{
res = new Result() { Succeed = true, ResultData = RFID, ErrorMessage = "" };
Log.Info(string.Format("WebService Request(GET) emptyStation={0},rfid={1}", line, RFID));
Common.LogInfo("任务[GET]:" + value + " 出空料架 [emptyStation=" + line + ",rfid="+RFID+"]");
}
}
else
{
res = new Result() { Succeed = false, ResultData = null, ErrorMessage = "Not find " + line };
AGVControl.Common.LogInfo("WebService GET Response false " + "Not find " + line);
}
//Log.Info(string.Format("WebService GET Request emptyStation={0},rfid={1}", line, RFID));
return JsonHelper.SerializeObject(res);
}
}
public class WebService
{
private WebServiceHost _serviceHost;
public void Open(string url)
{
try
{
ClsWebService service = new ClsWebService();
_serviceHost = new WebServiceHost(service, new Uri(url));//service, new Uri(url)
_serviceHost.Open();
AGVControl.Common.LogInfo("Web服务已开启");
}
catch (Exception ex)
{
AGVControl.Common.log.Error("Open", ex);
}
}
public void Close()
{
try
{
if (_serviceHost != null)//判断服务是否关闭
_serviceHost.Close();//关闭服务
Common.log.Info("Web服务已关闭");
}
catch (Exception ex)
{
Common.log.Error("Close", ex);
}
}
//public void RecycleTask(string lineName)
//{
// if (AGVControl.Common.agvProductionLine.TryGetValue(lineName, out string value))
// {
// AGVControl.Common.LogInfo("WebService Response OK");
// //加到任务
// //int idx = AGVControl.Common.nodeInfo.FindIndex(s => s.Name == value);
// //if (idx > -1)
// // AGVControl.Common.linePlace.Add(value);
// //else
// // AGVControl.Common.log.Error("CreateEmptyRecycleTask " + value + "不存在");
// if (!Common.AddLinePlace(value))
// Common.log.Error("CreateEmptyRecycleTask 节点【" + value + "】不存在");
// else
// {
// Common.LogInfo("任务:" + value + " 出空料架 【" + lineName + "】");
// }
// //System.IO.File.WriteAllLines(Common.CONFIG_PATH + "LinePlace.txt", Common.linePlace);
// }
// else
// {
// AGVControl.Common.LogInfo("WebService Response false");
// }
//}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Script.Serialization;
using AGVControl;
using RestSharp;
namespace BLL
{
public class MiR_API
{
private const int httpTimeout = 5000;
public MiR_API()
{
}
/// <summary>
/// 获取IO模块guid列表
/// </summary>
/// <param name="info"></param>
/// <param name="guid"></param>
/// <returns></returns>
//public bool Get_IO_Modules(AGVControl.Agv_Info info, out string[] guid)
//{
// try
// {
// guid = null;
// string url = "http://" + info.IP + "/api/v2.0.0/status?whitelist=state_id,state_text";
// string json = HttpGet(url, info.IP, info.Authorization);
// //LogInfo("URL: " + url+"\n"+"Return: " + json);
// if (string.IsNullOrWhiteSpace(json)) return false;
// JavaScriptSerializer serializer = new JavaScriptSerializer();
// object[] obj = (object[])serializer.DeserializeObject(json);
// if (obj == null) return false;
// guid = new string[obj.Length];
// for (int i = 0; i < obj.Length; i++)
// {
// Dictionary<string, object> dic = (Dictionary<string, object>)obj[i];
// guid[i] = dic["guid"].ToString();
// }
// return true;
// }
// catch (Exception ex)
// {
// guid = null;
// Common.log.Error("Get_IO_Modules", ex);
// return false;
// }
//}
/// <summary>
/// 获取IO模块的状态
/// </summary>
/// <param name="info"></param>
/// <param name="input"></param>
/// <param name="output"></param>
/// <returns></returns>
public bool Get_IO_Status(Agv_Info info, out bool[] input, out bool[] output)
{
try
{
input = null;
output = null;
string url = "http://" + info.IP + "/api/v2.0.0/io_modules/" + info.IOID + "/status";
string json = HttpGet(url, info.IP, info.Authorization);
Common.log.Debug("URL: " + url + "\n" + "Return: " + json);
if (string.IsNullOrWhiteSpace(json)) return false;
JavaScriptSerializer serializer = new JavaScriptSerializer();
Dictionary<string, object> dic = (Dictionary<string, object>)serializer.DeserializeObject(json);
if (dic == null) return false;
object[] objInput = (object[])dic["input_state"];
input = new bool[objInput.Length];
for (int i = 0; i < input.Length; i++)
input[i] = Convert.ToBoolean(objInput[i]);
object[] objOutput = (object[])dic["output_state"];
output = new bool[objOutput.Length];
for (int i = 0; i < output.Length; i++)
output[i] = Convert.ToBoolean(objOutput[i]);
return true;
}
catch (Exception ex)
{
input = null;
output = null;
//Common.log.Error("", ex);
return false;
}
}
/// <summary>
/// 获取PLC寄存器的内容
/// </summary>
/// <param name="info"></param>
/// <param name="reg"></param>
/// <param name="regValue"></param>
/// <returns></returns>
public bool Get_Register(Agv_Info info, int reg, out int regValue)
{
try
{
regValue = -1;
string url = "http://" + info.IP + "/api/v2.0.0/registers/" + reg + "?whitelist=value";
string json = HttpGet(url, info.IP, info.Authorization);
if (string.IsNullOrWhiteSpace(json)) return false;
JavaScriptSerializer serializer = new JavaScriptSerializer();
Dictionary<string, object> dic = (Dictionary<string, object>)serializer.DeserializeObject(json);
if (dic == null) return false;
string s = dic["value"].ToString();
float f = Convert.ToSingle(s);
regValue = Convert.ToInt32(f);
return true;
}
catch (Exception ex)
{
regValue = -1;
Common.log.Error("Get_Register", ex);
return false;
}
}
/// <summary>
/// 设置PLC寄存器的内容
/// </summary>
/// <param name="info"></param>
/// <param name="reg"></param>
/// <param name="regValue"></param>
/// <returns></returns>
public bool Set_Register(Agv_Info info, int reg, int regValue)
{
try
{
string url = "http://" + info.IP + "/api/v2.0.0/registers/" + reg;
string body = "{\"value\": " + regValue + "}";
string json = HttpPost(url, info.IP, info.Authorization, body);
if (string.IsNullOrWhiteSpace(json)) return false;
JavaScriptSerializer serializer = new JavaScriptSerializer();
Dictionary<string, object> dic = (Dictionary<string, object>)serializer.DeserializeObject(json);
if (dic == null) return false;
string s = dic["value"].ToString();
float f = Convert.ToSingle(s);
if (regValue == Convert.ToInt32(f))
return true;
else
return false;
}
catch (Exception ex)
{
Common.log.Error("Set_Register", ex);
return false;
}
}
/// <summary>
/// 添加任务到任务队列
/// </summary>
/// <param name="info"></param>
/// <param name="mission_id"></param>
/// <returns></returns>
public bool Add_Mission(Agv_Info info, string mission_id, bool isRemovePreMission = true)
{
try
{
//var key = Common.agvMission.Where(qq => qq.Value == mission_id).Select(qq => qq.Key);
//Common.log.Info(string.Format("{0} Add_Mission [{1}]", info.Name, key.ToList()[0]));
Common.LogInfo(string.Format("{0} Add_Mission [{1}]", info.Name, mission_id));
//防止上一个任务已执行但返回失败时,删除任务
// if (isRemovePreMission)
Del_Mission(info);
string url = "http://" + info.IP + "/api/v2.0.0/mission_queue";
string body = "{\"mission_id\":\"" + mission_id + "\"}";
string json = HttpPost(url, info.IP, info.Authorization, body);
if (string.IsNullOrWhiteSpace(json)) return false;
JavaScriptSerializer serializer = new JavaScriptSerializer();
Dictionary<string, object> dic = (Dictionary<string, object>)serializer.DeserializeObject(json);
if (dic == null) return false;
string s = dic["mission_id"].ToString();
string id = dic["id"].ToString();
if (s == mission_id)
{
try
{
info.CurTaskID = Convert.ToInt32(id);
info.CurTaskGUID = mission_id;
var key = Common.agvMission.Where(qq => qq.Value == mission_id).Select(qq => qq.Key);
info.CurTaskName = key.ToList()[0];
Common.LogInfo(string.Format("{0} Add_Mission [{1}]", info.Name, key.ToList()[0]));
}
catch
{
Common.LogInfo(string.Format("{0} Add_Mission [{1}]", info.Name, mission_id));
info.CurTaskName = "";
}
return true;
}
else
return false;
}
catch (Exception ex)
{
Common.log.Error("Add_Mission", ex);
return false;
}
}
/// <summary>
/// 添加任务到任务队列
/// </summary>
/// <param name="info"></param>
/// <param name="mission_id"></param>
/// <returns></returns>
public bool Add_Mission_Fleet(Agv_Info info, string mission_id, bool isRemovePreMission = true)
{
try
{
//var key = Common.agvMission.Where(qq => qq.Value == mission_id).Select(qq => qq.Key);
//Common.log.Info(string.Format("{0} Add_Mission_Fleet [{1}]", info.Name, key.ToList()[0]));
var key = Common.agvMission.Where(qq => qq.Value == mission_id).Select(qq => qq.Key);
info.CurTaskName = key.ToList()[0];
Common.LogInfo(string.Format("{0} Add_Mission_Fleet [{1}][{2}]", info.Name, key.ToList()[0], mission_id));
info.CurTaskID = -1;
info.CurTaskGUID = "";
info.CurTaskState = SettingString.Wait;
//防止上一个任务已执行但返回失败时,删除任务
//if (isRemovePreMission)
Del_Mission(info);
string ip = Common.appConfig.AppSettings.Settings["FLEET"].Value;
string url = "http://" + ip + "/api/v2.0.0/mission_scheduler";
string body = "{\"mission_id\":\"" + mission_id + "\",\"robot_id\":" + info.ID + "}";
string json = HttpPost(url, info.IP, info.Authorization, body);
if (string.IsNullOrWhiteSpace(json)) return false;
JavaScriptSerializer serializer = new JavaScriptSerializer();
Dictionary<string, object> dic = (Dictionary<string, object>)serializer.DeserializeObject(json);
if (dic == null) return false;
string s = dic["mission_id"].ToString();
string id = dic["id"].ToString();
if (s == mission_id)
{
try
{
info.CurTaskID = Convert.ToInt32(id);
info.CurTaskGUID = mission_id;
}
catch
{
Common.LogInfo(string.Format("{0} Add_Mission_Fleet [{1}]", info.Name, mission_id));
info.CurTaskName = "";
}
return true;
}
else
return false;
}
catch (Exception ex)
{
Common.log.Error("Add_Mission_Fleet", ex);
return false;
}
}
/// <summary>
/// 获取所有任务列表
/// </summary>
/// <param name="info"></param>
/// <param name="mission">任务(名称,guid)</param>
/// <returns></returns>
public bool Get_Mission(Agv_Info info, out Dictionary<string, string> mission)
{
mission = null;
try
{
string url = "http://" + info.IP + "/api/v2.0.0/missions/search?whitelist=guid,name";
string body = "{\"filters\" :[]}";
string json = HttpPost(url, info.IP, info.Authorization, body);
if (string.IsNullOrWhiteSpace(json)) return false;
JavaScriptSerializer serializer = new JavaScriptSerializer();
object[] obj = (object[])serializer.DeserializeObject(json);
if (obj == null) return false;
mission = new Dictionary<string, string>();
for (int i = 0; i < obj.Length; i++)
{
Dictionary<string, object> dic = (Dictionary<string, object>)obj[i];
mission.Add(dic["name"].ToString(), dic["guid"].ToString());
}
return true;
}
catch (Exception ex)
{
Common.log.Error("Get_Mission", ex);
return false;
}
}
/// <summary>
/// 获取当前任务队列guid
/// </summary>
/// <param name="info"></param>
/// <param name="mission"></param>
/// <returns></returns>
public bool Get_Mission_Queue(Agv_Info info, out List<string> mission)
{
mission = null;
try
{
string url = "http://" + info.IP + "/api/v2.0.0/mission_queue/search";
string body = "{\"filters\" : [{\"fieldname\": \"state\", \"operator\": \"IN\", \"value\": [\"Pending\", \"Executing\"]}]}";
string json = HttpPost(url, info.IP, info.Authorization, body);
if (string.IsNullOrWhiteSpace(json)) return false;
JavaScriptSerializer serializer = new JavaScriptSerializer();
object[] obj = (object[])serializer.DeserializeObject(json);
if (obj == null) return false;
mission = new List<string>();
Dictionary<string, object> dic;
for (int i = 0; i < obj.Length; i++)
{
dic = (Dictionary<string, object>)obj[i];
mission.Add(dic["id"].ToString());
}
for (int i = 0; i < mission.Count; i++)
{
url = "http://" + info.IP + "/api/v2.0.0/mission_queue/" + mission[i];
json = HttpGet(url, info.IP, info.Authorization);
serializer = new JavaScriptSerializer();
dic = (Dictionary<string, object>)serializer.DeserializeObject(json);
mission[i] = dic["mission_id"].ToString();
}
return true;
}
catch (Exception ex)
{
Common.log.Error("Get_Mission_Queue", ex);
return false;
}
}
/// <summary>
/// 删除当前所有任务
/// </summary>
/// <param name="info"></param>
public void Del_Mission(Agv_Info info)
{
try
{
string url = "http://" + info.IP + "/api/v2.0.0/mission_queue";
HttpDel(url, info.IP, info.Authorization);
}
catch (Exception ex)
{
Common.log.Error("Del_Mission", ex);
}
}
/// <summary>
/// 获取当前小车状态
/// </summary>
/// <param name="info"></param>
/// <param name="stateID"></param>
/// <param name="stateText"></param>
/// <param name="battery"></param>
/// <param name="mission_text"></param>
/// <returns></returns>
public bool Get_State(Agv_Info info, out eAGVState stateID, out string stateText, out int battery, out string mission_text, out Agv_Info.clsPosition position)
{
stateID = eAGVState.UNKNOWN;
stateText = "";
battery = 0;
mission_text = "";
position = new Agv_Info.clsPosition();
try
{
string url = "http://" + info.IP + "/api/v2.0.0/status?whitelist=state_id,state_text,battery_percentage,mission_text,position";
string json = HttpGet(url, info.IP, info.Authorization);
if (string.IsNullOrWhiteSpace(json)) return false;
JavaScriptSerializer serializer = new JavaScriptSerializer();
Dictionary<string, object> dic = (Dictionary<string, object>)serializer.DeserializeObject(json);
if (dic == null) return false;
//state_id不存在:{"args":{},"error_code":"service_unavailable","error_human":"\u670d\u52a1\u4e0d\u53ef\u7528\uff0c\u8bf7\u7a0d\u540e\u91cd\u8bd5"}
Common.log.Debug("Get_State URL:"+url +" Return"+ json);
try
{
stateID = (eAGVState)(Convert.ToInt32(dic["state_id"].ToString()));
}
catch
{
Common.log.Error("获取状态失败:" +info.IP+" "+ json);
return false;
}
stateID = (eAGVState)(Convert.ToInt32(dic["state_id"].ToString()));
stateText = dic["state_text"].ToString();
mission_text = dic["mission_text"].ToString();
string s = dic["battery_percentage"].ToString();
float f = Convert.ToSingle(s);
battery = Convert.ToInt32(f);
Dictionary<string, object> posDic = (Dictionary<string, object>)dic["position"];
if (posDic == null) return false;
position.orientation = Convert.ToDouble(posDic["orientation"].ToString());
position.x = Convert.ToDouble(posDic["x"]);
position.y = Convert.ToDouble(posDic["y"]);
return true;
}
catch (Exception ex)
{
Common.log.Error("Get_State: ", ex);
return false;
}
}
public bool Get_Task_State(int CurTaskID, out string stateStr)
{
stateStr = SettingString.Wait;
try
{
if (CurTaskID == -1)
return true;
string ip = Common.appConfig.AppSettings.Settings["FLEET"].Value;
//http://10.85.199.3/api/v2.0.0/mission_scheduler
string url = "http://" + ip + "/api/v2.0.0/mission_scheduler/" + CurTaskID;
string json = HttpGet(url, ip, Common.agvInfo[0].Authorization);
Common.log.Debug("URL: " + url + "\n" + "Return: " + json);
if (string.IsNullOrWhiteSpace(json)) return false;
JavaScriptSerializer serializer = new JavaScriptSerializer();
Dictionary<string, object> dic = (Dictionary<string, object>)serializer.DeserializeObject(json);
if (dic == null) return false;
// "mission_id": "2e433130-c045-11ea-9a66-94c691a7387d",
// "id": 7178,
// "state": "Done"
string s = dic["id"].ToString();
if (s.Equals(CurTaskID.ToString()))
{
stateStr = dic["state"].ToString();
return true;
}
return false;
}
catch(Exception ex)
{
Common.log.Error("Get_Task_State", ex);
return false;
}
}
/// <summary>
/// 获取节点位置
/// </summary>
public bool Get_Node_Pos(Agv_Info agv, ClientNode clientNode, out MirPosition mirPosition)
{
try
{
if (clientNode.Pos_guid.Equals(""))
{
mirPosition = null;
return false;
}
string url = "http://" + agv.IP + "/api/v2.0.0/positions/" + clientNode.Pos_guid;
string json = HttpGet(url, agv.IP, agv.Authorization);
if (string.IsNullOrWhiteSpace(json))
{
mirPosition = null;
return false;
}
mirPosition = JsonHelper.DeserializeJsonToObject<MirPosition>(json);
if (mirPosition == null)
{
mirPosition = null;
return false;
}
return true;
}
catch (Exception ex)
{
Common.log.Error("Get_Node_Pos", ex);
mirPosition = null;
return false;
}
}
/// <summary>
/// 小车状态改为Ready
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
public bool State_Ready(Agv_Info info)
{
try
{
string url = "http://" + info.IP + "/api/v2.0.0/status?whitelist=state_id,state_text";
string body = "{\"state_id\": 3}";
string json = HttpPut(url, info.IP, info.Authorization, body);
if (string.IsNullOrWhiteSpace(json)) return false;
JavaScriptSerializer serializer = new JavaScriptSerializer();
Dictionary<string, object> dic = (Dictionary<string, object>)serializer.DeserializeObject(json);
if (dic == null) return false;
string s = dic["state_id"].ToString();
if (s == "3")
return true;
else
return false;
}
catch (Exception ex)
{
Common.log.Error("State_Ready", ex);
return false;
}
}
/// <summary>
/// 小车状态改为Pause
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
public bool State_Pause(Agv_Info info)
{
try
{
string url = "http://" + info.IP + "/api/v2.0.0/status?whitelist=state_id,state_text";
string body = "{\"state_id\": 4}";
string json = HttpPut(url, info.IP, info.Authorization, body);
if (string.IsNullOrWhiteSpace(json)) return false;
JavaScriptSerializer serializer = new JavaScriptSerializer();
Dictionary<string, object> dic = (Dictionary<string, object>)serializer.DeserializeObject(json);
if (dic == null) return false;
string s = dic["state_id"].ToString();
if (s == "4")
return true;
else
return false;
}
catch (Exception ex)
{
Common.log.Error("State_Pause", ex);
return false;
}
}
/// <summary>
/// 清除错误
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
public bool Clear_Error(Agv_Info info)
{
try
{
string url = "http://" + info.IP + "/api/v2.0.0/status";
string body = "{\"clear_error\": true}";
string json = HttpPut(url, info.IP, info.Authorization, body);
if (string.IsNullOrWhiteSpace(json)) return false;
return true;
}
catch (Exception ex)
{
Common.log.Error("Clear_Error", ex);
return false;
}
}
/// <summary>
/// 检查IP地址
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
public bool CheckIP(string ip)
{
//IP合法
string pattern = @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$";
bool rtn = System.Text.RegularExpressions.Regex.IsMatch(ip, pattern);
if (!rtn)
{
Common.log.Info("非法的IP地址" + ip);
return false;
}
//Ping服务端
try
{
System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
System.Net.NetworkInformation.PingReply result = ping.Send(ip, 2000);
ping.Dispose();
if (result.Status != System.Net.NetworkInformation.IPStatus.Success)
{
Common.log.Info("Ping " + ip + " 请求没有响应");
return false;
}
return true;
}
catch (Exception ex)
{
Common.log.Error("CheckIP", ex);
return false;
}
}
private string HttpGet(string url, string ip, string authorization)
{
RestClient client = new RestClient(url) { Timeout = httpTimeout };
RestRequest request = new RestRequest(Method.GET);
request.AddHeader("Host", ip);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept-Language", "zh_CN");
request.AddHeader("Authorization", authorization);
IRestResponse response = client.Execute(request);
string s = response.Content;
s = s.Replace("\n", "");
s = s.Replace(" ", "");
Common.log.Debug("HttpGet URL: " + url + " Return: " + s);
return s;
}
private string HttpPost(string url, string ip, string authorization, string body)
{
var client = new RestClient(url) { Timeout = httpTimeout };
var request = new RestRequest(Method.POST);
request.AddHeader("Host", ip);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept-Language", "zh_CN");
request.AddHeader("Authorization", authorization);
request.AddParameter("application/json", body, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
string s = response.Content;
s = s.Replace("\n", "");
s = s.Replace(" ", "");
Common.log.Debug(string.Format("HttpPost URL: {0}; Body: {1} Return: {2}", url, body, s));
return s;
}
private string HttpPut(string url, string ip, string authorization, string body)
{
RestClient client = new RestClient(url) { Timeout = httpTimeout };
RestRequest request = new RestRequest(Method.PUT);
request.AddHeader("Host", ip);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept-Language", "zh_CN");
request.AddHeader("Authorization", authorization);
request.AddParameter("application/json", body, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
string s = response.Content;
s = s.Replace("\n", "");
s = s.Replace(" ", "");
Common.log.Debug(string.Format("HttpPut URL: {0}; Body: {1} Return: {2}", url, body, s));
return s;
}
private void HttpDel(string url, string ip, string authorization)
{
RestClient client = new RestClient(url) { Timeout = httpTimeout };
RestRequest request = new RestRequest(Method.DELETE);
request.AddHeader("Host", ip);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Authorization", authorization);
request.AddHeader("Accept-Language", "zh_CN");
request.AddParameter("application/json", "", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
string s = response.Content;
Common.log.Debug("HttpDel URL: " + url);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
namespace BLL
{
public class MyWebClient:WebClient
{
private int _timeout;
/// <summary>
/// 超时时间(毫秒)
/// </summary>
public int Timeout
{
get
{
return _timeout;
}
set
{
_timeout = value;
}
}
public MyWebClient()
{
this._timeout = 60000;
}
public MyWebClient(int timeout)
{
this._timeout = timeout;
}
protected override WebRequest GetWebRequest(Uri address)
{
var result = base.GetWebRequest(address);
result.Timeout = this._timeout;
return result;
}
}
}
文件属性发生变化
namespace AGVControl
{
partial class FrmMain
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmMain));
this.DgvAgv = new System.Windows.Forms.DataGridView();
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.DgvNode = new System.Windows.Forms.DataGridView();
this.Column6 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column12 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column22 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column7 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column10 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column9 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column5 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column16 = new System.Windows.Forms.DataGridViewButtonColumn();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel5 = new System.Windows.Forms.TableLayoutPanel();
this.groupBox5 = new System.Windows.Forms.GroupBox();
this.lblDestInfo = new System.Windows.Forms.Label();
this.groupBox3 = new System.Windows.Forms.GroupBox();
this.lblWO = new System.Windows.Forms.Label();
this.tableLayoutPanel7 = new System.Windows.Forms.TableLayoutPanel();
this.groupBox4 = new System.Windows.Forms.GroupBox();
this.dgvLineMission = new System.Windows.Forms.DataGridView();
this.Column24 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column8 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.groupBox8 = new System.Windows.Forms.GroupBox();
this.lblStandy2 = new System.Windows.Forms.Label();
this.lblStandy1 = new System.Windows.Forms.Label();
this.lblCharge4 = new System.Windows.Forms.Label();
this.lblCharge3 = new System.Windows.Forms.Label();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.TxtLog = new System.Windows.Forms.TextBox();
this.tabPage3 = new System.Windows.Forms.TabPage();
this.groupBox7 = new System.Windows.Forms.GroupBox();
this.txtBoxLineName = new System.Windows.Forms.TextBox();
this.label8 = new System.Windows.Forms.Label();
this.label7 = new System.Windows.Forms.Label();
this.btnUpdateStatus = new System.Windows.Forms.Button();
this.txtBoxRFID = new System.Windows.Forms.TextBox();
this.groupBox6 = new System.Windows.Forms.GroupBox();
this.btnDeleteMission = new System.Windows.Forms.Button();
this.btnAddMission = new System.Windows.Forms.Button();
this.cmbBoxLineName = new System.Windows.Forms.ComboBox();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.btnReSendTask = new System.Windows.Forms.Button();
this.BtnClearError = new System.Windows.Forms.Button();
this.BtnMissionReady = new System.Windows.Forms.Button();
this.BtnMissionPause = new System.Windows.Forms.Button();
this.BtnMissionAdd = new System.Windows.Forms.Button();
this.LstAgvPlace = new System.Windows.Forms.ListBox();
this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
this.tableLayoutPanel6 = new System.Windows.Forms.TableLayoutPanel();
this.label6 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column4 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column14 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column21 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column3 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column18 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column23 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column13 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column19 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column11 = new System.Windows.Forms.DataGridViewButtonColumn();
((System.ComponentModel.ISupportInitialize)(this.DgvAgv)).BeginInit();
this.tableLayoutPanel3.SuspendLayout();
this.tabControl1.SuspendLayout();
this.tabPage1.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.DgvNode)).BeginInit();
this.groupBox1.SuspendLayout();
this.tableLayoutPanel5.SuspendLayout();
this.groupBox5.SuspendLayout();
this.groupBox3.SuspendLayout();
this.tableLayoutPanel7.SuspendLayout();
this.groupBox4.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.dgvLineMission)).BeginInit();
this.groupBox8.SuspendLayout();
this.tabPage2.SuspendLayout();
this.tableLayoutPanel1.SuspendLayout();
this.tabPage3.SuspendLayout();
this.groupBox7.SuspendLayout();
this.groupBox6.SuspendLayout();
this.groupBox2.SuspendLayout();
this.tableLayoutPanel4.SuspendLayout();
this.tableLayoutPanel6.SuspendLayout();
this.SuspendLayout();
//
// DgvAgv
//
this.DgvAgv.AllowUserToAddRows = false;
this.DgvAgv.AllowUserToDeleteRows = false;
this.DgvAgv.AllowUserToResizeColumns = false;
this.DgvAgv.AllowUserToResizeRows = false;
this.DgvAgv.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.DgvAgv.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
this.DgvAgv.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.AllCells;
this.DgvAgv.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.DgvAgv.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.Column1,
this.Column2,
this.Column4,
this.Column14,
this.Column21,
this.Column3,
this.Column18,
this.Column23,
this.Column13,
this.Column19,
this.Column11});
this.DgvAgv.Location = new System.Drawing.Point(3, 3);
this.DgvAgv.MultiSelect = false;
this.DgvAgv.Name = "DgvAgv";
this.DgvAgv.ReadOnly = true;
this.DgvAgv.RowHeadersVisible = false;
this.DgvAgv.RowHeadersWidth = 51;
this.DgvAgv.RowTemplate.Height = 23;
this.DgvAgv.Size = new System.Drawing.Size(1061, 125);
this.DgvAgv.TabIndex = 3;
this.DgvAgv.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.DgvAgv_CellClick);
//
// tableLayoutPanel3
//
this.tableLayoutPanel3.ColumnCount = 1;
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel3.Controls.Add(this.tabControl1, 0, 2);
this.tableLayoutPanel3.Controls.Add(this.DgvAgv, 0, 0);
this.tableLayoutPanel3.Controls.Add(this.tableLayoutPanel4, 0, 1);
this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel3.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
this.tableLayoutPanel3.RowCount = 3;
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F));
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 30F));
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel3.Size = new System.Drawing.Size(1067, 656);
this.tableLayoutPanel3.TabIndex = 7;
//
// tabControl1
//
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Controls.Add(this.tabPage3);
this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabControl1.Location = new System.Drawing.Point(3, 330);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(1061, 323);
this.tabControl1.TabIndex = 7;
//
// tabPage1
//
this.tabPage1.Controls.Add(this.tableLayoutPanel2);
this.tabPage1.Location = new System.Drawing.Point(4, 22);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3, 3, 3, 3);
this.tabPage1.Size = new System.Drawing.Size(1053, 297);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "节点状态&产线任务";
this.tabPage1.UseVisualStyleBackColor = true;
//
// tableLayoutPanel2
//
this.tableLayoutPanel2.ColumnCount = 2;
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 56.39743F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 43.60257F));
this.tableLayoutPanel2.Controls.Add(this.DgvNode, 0, 0);
this.tableLayoutPanel2.Controls.Add(this.groupBox1, 1, 0);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 3);
this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 1;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(1047, 291);
this.tableLayoutPanel2.TabIndex = 34;
//
// DgvNode
//
this.DgvNode.AllowUserToAddRows = false;
this.DgvNode.AllowUserToDeleteRows = false;
this.DgvNode.AllowUserToResizeColumns = false;
this.DgvNode.AllowUserToResizeRows = false;
this.DgvNode.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.DgvNode.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
this.DgvNode.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.AllCells;
this.DgvNode.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.DgvNode.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.Column6,
this.Column12,
this.Column22,
this.Column7,
this.Column10,
this.Column9,
this.Column5,
this.Column16});
this.DgvNode.Location = new System.Drawing.Point(3, 3);
this.DgvNode.MultiSelect = false;
this.DgvNode.Name = "DgvNode";
this.DgvNode.ReadOnly = true;
this.DgvNode.RowHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single;
this.DgvNode.RowHeadersVisible = false;
this.DgvNode.RowHeadersWidth = 50;
this.DgvNode.RowTemplate.Height = 23;
this.DgvNode.Size = new System.Drawing.Size(584, 285);
this.DgvNode.TabIndex = 1;
this.DgvNode.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.DgvNode_CellClick);
//
// Column6
//
this.Column6.FillWeight = 107.563F;
this.Column6.HeaderText = "地点";
this.Column6.MinimumWidth = 6;
this.Column6.Name = "Column6";
this.Column6.ReadOnly = true;
this.Column6.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
//
// Column12
//
this.Column12.FillWeight = 107.563F;
this.Column12.HeaderText = "IP";
this.Column12.MinimumWidth = 6;
this.Column12.Name = "Column12";
this.Column12.ReadOnly = true;
this.Column12.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
//
// Column22
//
this.Column22.FillWeight = 107.563F;
this.Column22.HeaderText = "解绑数";
this.Column22.MinimumWidth = 6;
this.Column22.Name = "Column22";
this.Column22.ReadOnly = true;
this.Column22.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
//
// Column7
//
this.Column7.FillWeight = 107.563F;
this.Column7.HeaderText = "动作";
this.Column7.MinimumWidth = 6;
this.Column7.Name = "Column7";
this.Column7.ReadOnly = true;
this.Column7.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
//
// Column10
//
this.Column10.FillWeight = 47.05883F;
this.Column10.HeaderText = "等级";
this.Column10.MinimumWidth = 6;
this.Column10.Name = "Column10";
this.Column10.ReadOnly = true;
//
// Column9
//
this.Column9.FillWeight = 107.563F;
this.Column9.HeaderText = "RFID";
this.Column9.MinimumWidth = 6;
this.Column9.Name = "Column9";
this.Column9.ReadOnly = true;
this.Column9.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
//
// Column5
//
this.Column5.FillWeight = 107.563F;
this.Column5.HeaderText = "连接";
this.Column5.MinimumWidth = 6;
this.Column5.Name = "Column5";
this.Column5.ReadOnly = true;
this.Column5.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
//
// Column16
//
this.Column16.FillWeight = 107.563F;
this.Column16.HeaderText = "调用";
this.Column16.MinimumWidth = 6;
this.Column16.Name = "Column16";
this.Column16.ReadOnly = true;
//
// groupBox1
//
this.groupBox1.Controls.Add(this.tableLayoutPanel5);
this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.groupBox1.Font = new System.Drawing.Font("宋体", 10.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.groupBox1.Location = new System.Drawing.Point(592, 2);
this.groupBox1.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Padding = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.groupBox1.Size = new System.Drawing.Size(453, 287);
this.groupBox1.TabIndex = 33;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "任务信息";
//
// tableLayoutPanel5
//
this.tableLayoutPanel5.ColumnCount = 1;
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel5.Controls.Add(this.groupBox5, 0, 1);
this.tableLayoutPanel5.Controls.Add(this.groupBox3, 0, 0);
this.tableLayoutPanel5.Controls.Add(this.tableLayoutPanel7, 0, 2);
this.tableLayoutPanel5.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel5.Location = new System.Drawing.Point(2, 19);
this.tableLayoutPanel5.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.tableLayoutPanel5.Name = "tableLayoutPanel5";
this.tableLayoutPanel5.RowCount = 3;
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 15F));
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 15F));
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 70F));
this.tableLayoutPanel5.Size = new System.Drawing.Size(449, 266);
this.tableLayoutPanel5.TabIndex = 2;
//
// groupBox5
//
this.groupBox5.Controls.Add(this.lblDestInfo);
this.groupBox5.Dock = System.Windows.Forms.DockStyle.Fill;
this.groupBox5.Location = new System.Drawing.Point(2, 41);
this.groupBox5.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.groupBox5.Name = "groupBox5";
this.groupBox5.Padding = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.groupBox5.Size = new System.Drawing.Size(445, 35);
this.groupBox5.TabIndex = 2;
this.groupBox5.TabStop = false;
this.groupBox5.Text = "出料信息";
//
// lblDestInfo
//
this.lblDestInfo.Dock = System.Windows.Forms.DockStyle.Fill;
this.lblDestInfo.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.lblDestInfo.Location = new System.Drawing.Point(2, 19);
this.lblDestInfo.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblDestInfo.Name = "lblDestInfo";
this.lblDestInfo.Size = new System.Drawing.Size(441, 14);
this.lblDestInfo.TabIndex = 40;
this.lblDestInfo.Text = "lblDestInfo";
//
// groupBox3
//
this.groupBox3.Controls.Add(this.lblWO);
this.groupBox3.Dock = System.Windows.Forms.DockStyle.Fill;
this.groupBox3.Location = new System.Drawing.Point(2, 2);
this.groupBox3.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.groupBox3.Name = "groupBox3";
this.groupBox3.Padding = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.groupBox3.Size = new System.Drawing.Size(445, 35);
this.groupBox3.TabIndex = 0;
this.groupBox3.TabStop = false;
this.groupBox3.Text = "双层线工单信息";
//
// lblWO
//
this.lblWO.Dock = System.Windows.Forms.DockStyle.Fill;
this.lblWO.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.lblWO.Location = new System.Drawing.Point(2, 19);
this.lblWO.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblWO.Name = "lblWO";
this.lblWO.Size = new System.Drawing.Size(441, 14);
this.lblWO.TabIndex = 40;
this.lblWO.Text = "lblWO";
//
// tableLayoutPanel7
//
this.tableLayoutPanel7.ColumnCount = 2;
this.tableLayoutPanel7.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 56.58784F));
this.tableLayoutPanel7.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 43.41216F));
this.tableLayoutPanel7.Controls.Add(this.groupBox4, 0, 0);
this.tableLayoutPanel7.Controls.Add(this.groupBox8, 1, 0);
this.tableLayoutPanel7.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel7.Location = new System.Drawing.Point(2, 80);
this.tableLayoutPanel7.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.tableLayoutPanel7.Name = "tableLayoutPanel7";
this.tableLayoutPanel7.RowCount = 1;
this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel7.Size = new System.Drawing.Size(445, 184);
this.tableLayoutPanel7.TabIndex = 3;
//
// groupBox4
//
this.groupBox4.Controls.Add(this.dgvLineMission);
this.groupBox4.Dock = System.Windows.Forms.DockStyle.Fill;
this.groupBox4.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.groupBox4.Location = new System.Drawing.Point(2, 2);
this.groupBox4.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.groupBox4.Name = "groupBox4";
this.groupBox4.Padding = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.groupBox4.Size = new System.Drawing.Size(247, 180);
this.groupBox4.TabIndex = 2;
this.groupBox4.TabStop = false;
this.groupBox4.Text = "产线解绑信息";
//
// dgvLineMission
//
this.dgvLineMission.AllowUserToAddRows = false;
dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control;
dataGridViewCellStyle1.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText;
dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
this.dgvLineMission.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1;
this.dgvLineMission.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dgvLineMission.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.Column24,
this.Column8});
dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Window;
dataGridViewCellStyle2.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.ControlText;
dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this.dgvLineMission.DefaultCellStyle = dataGridViewCellStyle2;
this.dgvLineMission.Dock = System.Windows.Forms.DockStyle.Fill;
this.dgvLineMission.Location = new System.Drawing.Point(2, 16);
this.dgvLineMission.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.dgvLineMission.Name = "dgvLineMission";
dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.Control;
dataGridViewCellStyle3.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
dataGridViewCellStyle3.ForeColor = System.Drawing.SystemColors.WindowText;
dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
this.dgvLineMission.RowHeadersDefaultCellStyle = dataGridViewCellStyle3;
this.dgvLineMission.RowHeadersVisible = false;
this.dgvLineMission.RowHeadersWidth = 51;
this.dgvLineMission.RowTemplate.Height = 27;
this.dgvLineMission.Size = new System.Drawing.Size(243, 162);
this.dgvLineMission.TabIndex = 28;
this.dgvLineMission.Click += new System.EventHandler(this.dgvLineMission_Click);
//
// Column24
//
this.Column24.HeaderText = "时间";
this.Column24.MinimumWidth = 6;
this.Column24.Name = "Column24";
this.Column24.Width = 150;
//
// Column8
//
this.Column8.HeaderText = "任务";
this.Column8.MinimumWidth = 6;
this.Column8.Name = "Column8";
this.Column8.Width = 150;
//
// groupBox8
//
this.groupBox8.Controls.Add(this.lblStandy2);
this.groupBox8.Controls.Add(this.lblStandy1);
this.groupBox8.Controls.Add(this.lblCharge4);
this.groupBox8.Controls.Add(this.lblCharge3);
this.groupBox8.Dock = System.Windows.Forms.DockStyle.Fill;
this.groupBox8.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.groupBox8.Location = new System.Drawing.Point(253, 2);
this.groupBox8.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.groupBox8.Name = "groupBox8";
this.groupBox8.Padding = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.groupBox8.Size = new System.Drawing.Size(190, 180);
this.groupBox8.TabIndex = 3;
this.groupBox8.TabStop = false;
this.groupBox8.Text = "位置占用情况";
//
// lblStandy2
//
this.lblStandy2.AutoSize = true;
this.lblStandy2.Dock = System.Windows.Forms.DockStyle.Top;
this.lblStandy2.Location = new System.Drawing.Point(2, 52);
this.lblStandy2.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblStandy2.Name = "lblStandy2";
this.lblStandy2.Size = new System.Drawing.Size(65, 12);
this.lblStandy2.TabIndex = 3;
this.lblStandy2.Text = "lblStandy2";
//
// lblStandy1
//
this.lblStandy1.AutoSize = true;
this.lblStandy1.Dock = System.Windows.Forms.DockStyle.Top;
this.lblStandy1.Location = new System.Drawing.Point(2, 40);
this.lblStandy1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblStandy1.Name = "lblStandy1";
this.lblStandy1.Size = new System.Drawing.Size(65, 12);
this.lblStandy1.TabIndex = 2;
this.lblStandy1.Text = "lblStandy1";
//
// lblCharge4
//
this.lblCharge4.AutoSize = true;
this.lblCharge4.Dock = System.Windows.Forms.DockStyle.Top;
this.lblCharge4.Location = new System.Drawing.Point(2, 28);
this.lblCharge4.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblCharge4.Name = "lblCharge4";
this.lblCharge4.Size = new System.Drawing.Size(65, 12);
this.lblCharge4.TabIndex = 1;
this.lblCharge4.Text = "lblCharge4";
//
// lblCharge3
//
this.lblCharge3.AutoSize = true;
this.lblCharge3.Dock = System.Windows.Forms.DockStyle.Top;
this.lblCharge3.Location = new System.Drawing.Point(2, 16);
this.lblCharge3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.lblCharge3.Name = "lblCharge3";
this.lblCharge3.Size = new System.Drawing.Size(65, 12);
this.lblCharge3.TabIndex = 0;
this.lblCharge3.Text = "lblCharge3";
//
// tabPage2
//
this.tabPage2.Controls.Add(this.tableLayoutPanel1);
this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3, 3, 3, 3);
this.tabPage2.Size = new System.Drawing.Size(1053, 297);
this.tabPage2.TabIndex = 3;
this.tabPage2.Text = "日志";
this.tabPage2.UseVisualStyleBackColor = true;
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 1;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 15F));
this.tableLayoutPanel1.Controls.Add(this.TxtLog, 0, 0);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 3);
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 1;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(1047, 291);
this.tableLayoutPanel1.TabIndex = 6;
//
// TxtLog
//
this.TxtLog.Dock = System.Windows.Forms.DockStyle.Fill;
this.TxtLog.Location = new System.Drawing.Point(3, 3);
this.TxtLog.Multiline = true;
this.TxtLog.Name = "TxtLog";
this.TxtLog.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.TxtLog.Size = new System.Drawing.Size(1041, 285);
this.TxtLog.TabIndex = 5;
//
// tabPage3
//
this.tabPage3.Controls.Add(this.groupBox7);
this.tabPage3.Controls.Add(this.groupBox6);
this.tabPage3.Controls.Add(this.groupBox2);
this.tabPage3.Controls.Add(this.BtnMissionAdd);
this.tabPage3.Controls.Add(this.LstAgvPlace);
this.tabPage3.Location = new System.Drawing.Point(4, 22);
this.tabPage3.Name = "tabPage3";
this.tabPage3.Padding = new System.Windows.Forms.Padding(3, 3, 3, 3);
this.tabPage3.Size = new System.Drawing.Size(1053, 297);
this.tabPage3.TabIndex = 2;
this.tabPage3.Text = "手动";
this.tabPage3.UseVisualStyleBackColor = true;
//
// groupBox7
//
this.groupBox7.Controls.Add(this.txtBoxLineName);
this.groupBox7.Controls.Add(this.label8);
this.groupBox7.Controls.Add(this.label7);
this.groupBox7.Controls.Add(this.btnUpdateStatus);
this.groupBox7.Controls.Add(this.txtBoxRFID);
this.groupBox7.Location = new System.Drawing.Point(518, 24);
this.groupBox7.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.groupBox7.Name = "groupBox7";
this.groupBox7.Padding = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.groupBox7.Size = new System.Drawing.Size(153, 121);
this.groupBox7.TabIndex = 36;
this.groupBox7.TabStop = false;
this.groupBox7.Text = "物料状态上报";
//
// txtBoxLineName
//
this.txtBoxLineName.Location = new System.Drawing.Point(60, 50);
this.txtBoxLineName.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.txtBoxLineName.Name = "txtBoxLineName";
this.txtBoxLineName.Size = new System.Drawing.Size(77, 21);
this.txtBoxLineName.TabIndex = 44;
//
// label8
//
this.label8.AutoSize = true;
this.label8.Location = new System.Drawing.Point(4, 58);
this.label8.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label8.Name = "label8";
this.label8.Size = new System.Drawing.Size(47, 12);
this.label8.TabIndex = 43;
this.label8.Text = "产线名:";
//
// label7
//
this.label7.AutoSize = true;
this.label7.Location = new System.Drawing.Point(4, 24);
this.label7.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(35, 12);
this.label7.TabIndex = 42;
this.label7.Text = "RFID:";
//
// btnUpdateStatus
//
this.btnUpdateStatus.Location = new System.Drawing.Point(37, 78);
this.btnUpdateStatus.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.btnUpdateStatus.Name = "btnUpdateStatus";
this.btnUpdateStatus.Size = new System.Drawing.Size(75, 39);
this.btnUpdateStatus.TabIndex = 41;
this.btnUpdateStatus.Text = "上报";
this.btnUpdateStatus.UseVisualStyleBackColor = true;
this.btnUpdateStatus.Click += new System.EventHandler(this.btnUpdateStatus_Click);
//
// txtBoxRFID
//
this.txtBoxRFID.Location = new System.Drawing.Point(60, 19);
this.txtBoxRFID.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.txtBoxRFID.Name = "txtBoxRFID";
this.txtBoxRFID.Size = new System.Drawing.Size(77, 21);
this.txtBoxRFID.TabIndex = 0;
//
// groupBox6
//
this.groupBox6.Controls.Add(this.btnDeleteMission);
this.groupBox6.Controls.Add(this.btnAddMission);
this.groupBox6.Controls.Add(this.cmbBoxLineName);
this.groupBox6.Location = new System.Drawing.Point(297, 21);
this.groupBox6.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.groupBox6.Name = "groupBox6";
this.groupBox6.Padding = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.groupBox6.Size = new System.Drawing.Size(191, 124);
this.groupBox6.TabIndex = 35;
this.groupBox6.TabStop = false;
this.groupBox6.Text = "产线绑定";
//
// btnDeleteMission
//
this.btnDeleteMission.Location = new System.Drawing.Point(92, 50);
this.btnDeleteMission.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.btnDeleteMission.Name = "btnDeleteMission";
this.btnDeleteMission.Size = new System.Drawing.Size(75, 52);
this.btnDeleteMission.TabIndex = 41;
this.btnDeleteMission.Text = "删除绑定任务";
this.btnDeleteMission.UseVisualStyleBackColor = true;
this.btnDeleteMission.Click += new System.EventHandler(this.btnDeleteMission_Click);
//
// btnAddMission
//
this.btnAddMission.Location = new System.Drawing.Point(4, 50);
this.btnAddMission.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.btnAddMission.Name = "btnAddMission";
this.btnAddMission.Size = new System.Drawing.Size(75, 52);
this.btnAddMission.TabIndex = 40;
this.btnAddMission.Text = "添加绑定任务";
this.btnAddMission.UseVisualStyleBackColor = true;
this.btnAddMission.Click += new System.EventHandler(this.btnAddMission_Click);
//
// cmbBoxLineName
//
this.cmbBoxLineName.FormattingEnabled = true;
this.cmbBoxLineName.Location = new System.Drawing.Point(4, 18);
this.cmbBoxLineName.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.cmbBoxLineName.Name = "cmbBoxLineName";
this.cmbBoxLineName.Size = new System.Drawing.Size(137, 20);
this.cmbBoxLineName.TabIndex = 39;
//
// groupBox2
//
this.groupBox2.Controls.Add(this.btnReSendTask);
this.groupBox2.Controls.Add(this.BtnClearError);
this.groupBox2.Controls.Add(this.BtnMissionReady);
this.groupBox2.Controls.Add(this.BtnMissionPause);
this.groupBox2.Location = new System.Drawing.Point(701, 24);
this.groupBox2.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Padding = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.groupBox2.Size = new System.Drawing.Size(262, 177);
this.groupBox2.TabIndex = 32;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "操作";
//
// btnReSendTask
//
this.btnReSendTask.Location = new System.Drawing.Point(152, 102);
this.btnReSendTask.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.btnReSendTask.Name = "btnReSendTask";
this.btnReSendTask.Size = new System.Drawing.Size(75, 52);
this.btnReSendTask.TabIndex = 45;
this.btnReSendTask.Text = "任务重发";
this.btnReSendTask.UseVisualStyleBackColor = true;
this.btnReSendTask.Click += new System.EventHandler(this.btnReSendTask_Click);
//
// BtnClearError
//
this.BtnClearError.Location = new System.Drawing.Point(35, 102);
this.BtnClearError.Name = "BtnClearError";
this.BtnClearError.Size = new System.Drawing.Size(75, 52);
this.BtnClearError.TabIndex = 19;
this.BtnClearError.Text = "清除错误";
this.BtnClearError.UseVisualStyleBackColor = true;
this.BtnClearError.Click += new System.EventHandler(this.BtnClearError_Click);
//
// BtnMissionReady
//
this.BtnMissionReady.Location = new System.Drawing.Point(35, 19);
this.BtnMissionReady.Name = "BtnMissionReady";
this.BtnMissionReady.Size = new System.Drawing.Size(75, 52);
this.BtnMissionReady.TabIndex = 1;
this.BtnMissionReady.Text = "运行";
this.BtnMissionReady.UseVisualStyleBackColor = true;
this.BtnMissionReady.Click += new System.EventHandler(this.BtnMissionReady_Click);
//
// BtnMissionPause
//
this.BtnMissionPause.Location = new System.Drawing.Point(152, 15);
this.BtnMissionPause.Name = "BtnMissionPause";
this.BtnMissionPause.Size = new System.Drawing.Size(75, 52);
this.BtnMissionPause.TabIndex = 2;
this.BtnMissionPause.Text = "暂停";
this.BtnMissionPause.UseVisualStyleBackColor = true;
this.BtnMissionPause.Click += new System.EventHandler(this.BtnMissionPause_Click);
//
// BtnMissionAdd
//
this.BtnMissionAdd.Location = new System.Drawing.Point(170, 24);
this.BtnMissionAdd.Name = "BtnMissionAdd";
this.BtnMissionAdd.Size = new System.Drawing.Size(75, 60);
this.BtnMissionAdd.TabIndex = 3;
this.BtnMissionAdd.Text = "添加任务";
this.BtnMissionAdd.UseVisualStyleBackColor = true;
this.BtnMissionAdd.Click += new System.EventHandler(this.BtnMissionAdd_Click);
//
// LstAgvPlace
//
this.LstAgvPlace.Dock = System.Windows.Forms.DockStyle.Left;
this.LstAgvPlace.FormattingEnabled = true;
this.LstAgvPlace.IntegralHeight = false;
this.LstAgvPlace.ItemHeight = 12;
this.LstAgvPlace.Location = new System.Drawing.Point(3, 3);
this.LstAgvPlace.Name = "LstAgvPlace";
this.LstAgvPlace.Size = new System.Drawing.Size(150, 291);
this.LstAgvPlace.TabIndex = 0;
//
// tableLayoutPanel4
//
this.tableLayoutPanel4.ColumnCount = 1;
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel4.Controls.Add(this.tableLayoutPanel6, 0, 0);
this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel4.Location = new System.Drawing.Point(2, 133);
this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.tableLayoutPanel4.Name = "tableLayoutPanel4";
this.tableLayoutPanel4.RowCount = 1;
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 169F));
this.tableLayoutPanel4.Size = new System.Drawing.Size(1063, 192);
this.tableLayoutPanel4.TabIndex = 8;
//
// tableLayoutPanel6
//
this.tableLayoutPanel6.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.OutsetPartial;
this.tableLayoutPanel6.ColumnCount = 3;
this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33334F));
this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33334F));
this.tableLayoutPanel6.Controls.Add(this.label6, 2, 1);
this.tableLayoutPanel6.Controls.Add(this.label5, 1, 1);
this.tableLayoutPanel6.Controls.Add(this.label4, 0, 1);
this.tableLayoutPanel6.Controls.Add(this.label3, 2, 0);
this.tableLayoutPanel6.Controls.Add(this.label2, 1, 0);
this.tableLayoutPanel6.Controls.Add(this.label1, 0, 0);
this.tableLayoutPanel6.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel6.Font = new System.Drawing.Font("宋体", 10.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.tableLayoutPanel6.Location = new System.Drawing.Point(2, 2);
this.tableLayoutPanel6.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.tableLayoutPanel6.Name = "tableLayoutPanel6";
this.tableLayoutPanel6.RowCount = 2;
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel6.Size = new System.Drawing.Size(1059, 188);
this.tableLayoutPanel6.TabIndex = 0;
//
// label6
//
this.label6.AutoSize = true;
this.label6.Dock = System.Windows.Forms.DockStyle.Fill;
this.label6.Font = new System.Drawing.Font("宋体", 10.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.label6.Location = new System.Drawing.Point(708, 95);
this.label6.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(346, 90);
this.label6.TabIndex = 5;
this.label6.Text = "label6";
//
// label5
//
this.label5.AutoSize = true;
this.label5.Dock = System.Windows.Forms.DockStyle.Fill;
this.label5.Font = new System.Drawing.Font("宋体", 10.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.label5.Location = new System.Drawing.Point(356, 95);
this.label5.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(345, 90);
this.label5.TabIndex = 4;
this.label5.Text = "label5";
//
// label4
//
this.label4.AutoSize = true;
this.label4.Dock = System.Windows.Forms.DockStyle.Fill;
this.label4.Font = new System.Drawing.Font("宋体", 10.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.label4.Location = new System.Drawing.Point(5, 95);
this.label4.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(344, 90);
this.label4.TabIndex = 3;
this.label4.Text = "label4";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Dock = System.Windows.Forms.DockStyle.Fill;
this.label3.Font = new System.Drawing.Font("宋体", 10.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.label3.Location = new System.Drawing.Point(708, 3);
this.label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(346, 89);
this.label3.TabIndex = 2;
this.label3.Text = "label3";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Dock = System.Windows.Forms.DockStyle.Fill;
this.label2.Font = new System.Drawing.Font("宋体", 10.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.label2.Location = new System.Drawing.Point(356, 3);
this.label2.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(345, 89);
this.label2.TabIndex = 1;
this.label2.Text = "label2";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
this.label1.Font = new System.Drawing.Font("宋体", 10.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.label1.Location = new System.Drawing.Point(5, 3);
this.label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(344, 89);
this.label1.TabIndex = 0;
this.label1.Text = "label1";
//
// Column1
//
this.Column1.HeaderText = "名称";
this.Column1.MinimumWidth = 6;
this.Column1.Name = "Column1";
this.Column1.ReadOnly = true;
this.Column1.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
//
// Column2
//
this.Column2.HeaderText = "IP";
this.Column2.MinimumWidth = 6;
this.Column2.Name = "Column2";
this.Column2.ReadOnly = true;
this.Column2.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
//
// Column4
//
this.Column4.HeaderText = "小车状态";
this.Column4.MinimumWidth = 6;
this.Column4.Name = "Column4";
this.Column4.ReadOnly = true;
this.Column4.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
//
// Column14
//
this.Column14.HeaderText = "任务ID";
this.Column14.MinimumWidth = 6;
this.Column14.Name = "Column14";
this.Column14.ReadOnly = true;
this.Column14.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
//
// Column21
//
this.Column21.HeaderText = "任务名称";
this.Column21.MinimumWidth = 6;
this.Column21.Name = "Column21";
this.Column21.ReadOnly = true;
this.Column21.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
//
// Column3
//
this.Column3.HeaderText = "任务状态";
this.Column3.MinimumWidth = 6;
this.Column3.Name = "Column3";
this.Column3.ReadOnly = true;
this.Column3.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
//
// Column18
//
this.Column18.HeaderText = "目的地";
this.Column18.MinimumWidth = 6;
this.Column18.Name = "Column18";
this.Column18.ReadOnly = true;
this.Column18.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
//
// Column23
//
this.Column23.HeaderText = "负载";
this.Column23.MinimumWidth = 6;
this.Column23.Name = "Column23";
this.Column23.ReadOnly = true;
this.Column23.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
//
// Column13
//
this.Column13.HeaderText = "连接";
this.Column13.MinimumWidth = 6;
this.Column13.Name = "Column13";
this.Column13.ReadOnly = true;
this.Column13.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
//
// Column19
//
this.Column19.HeaderText = "电量";
this.Column19.MinimumWidth = 6;
this.Column19.Name = "Column19";
this.Column19.ReadOnly = true;
this.Column19.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
//
// Column11
//
this.Column11.HeaderText = "自动";
this.Column11.MinimumWidth = 6;
this.Column11.Name = "Column11";
this.Column11.ReadOnly = true;
//
// FrmMain
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1067, 656);
this.Controls.Add(this.tableLayoutPanel3);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "FrmMain";
this.Text = "AGV产线调度";
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FrmMain_FormClosing);
this.Load += new System.EventHandler(this.FrmMain_Load);
((System.ComponentModel.ISupportInitialize)(this.DgvAgv)).EndInit();
this.tableLayoutPanel3.ResumeLayout(false);
this.tabControl1.ResumeLayout(false);
this.tabPage1.ResumeLayout(false);
this.tableLayoutPanel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.DgvNode)).EndInit();
this.groupBox1.ResumeLayout(false);
this.tableLayoutPanel5.ResumeLayout(false);
this.groupBox5.ResumeLayout(false);
this.groupBox3.ResumeLayout(false);
this.tableLayoutPanel7.ResumeLayout(false);
this.groupBox4.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.dgvLineMission)).EndInit();
this.groupBox8.ResumeLayout(false);
this.groupBox8.PerformLayout();
this.tabPage2.ResumeLayout(false);
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
this.tabPage3.ResumeLayout(false);
this.groupBox7.ResumeLayout(false);
this.groupBox7.PerformLayout();
this.groupBox6.ResumeLayout(false);
this.groupBox2.ResumeLayout(false);
this.tableLayoutPanel4.ResumeLayout(false);
this.tableLayoutPanel6.ResumeLayout(false);
this.tableLayoutPanel6.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.DataGridView DgvAgv;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
private System.Windows.Forms.DataGridView DgvNode;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.TextBox TxtLog;
private System.Windows.Forms.TabPage tabPage3;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.Button BtnClearError;
private System.Windows.Forms.Button BtnMissionAdd;
private System.Windows.Forms.Button BtnMissionPause;
private System.Windows.Forms.Button BtnMissionReady;
private System.Windows.Forms.ListBox LstAgvPlace;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4;
private System.Windows.Forms.Label lblWO;
private System.Windows.Forms.GroupBox groupBox3;
private System.Windows.Forms.DataGridViewTextBoxColumn Column6;
private System.Windows.Forms.DataGridViewTextBoxColumn Column12;
private System.Windows.Forms.DataGridViewTextBoxColumn Column22;
private System.Windows.Forms.DataGridViewTextBoxColumn Column7;
private System.Windows.Forms.DataGridViewTextBoxColumn Column10;
private System.Windows.Forms.DataGridViewTextBoxColumn Column9;
private System.Windows.Forms.DataGridViewTextBoxColumn Column5;
private System.Windows.Forms.DataGridViewButtonColumn Column16;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel6;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel5;
private System.Windows.Forms.GroupBox groupBox5;
private System.Windows.Forms.Label lblDestInfo;
private System.Windows.Forms.GroupBox groupBox6;
private System.Windows.Forms.Button btnDeleteMission;
private System.Windows.Forms.Button btnAddMission;
private System.Windows.Forms.ComboBox cmbBoxLineName;
private System.Windows.Forms.GroupBox groupBox7;
private System.Windows.Forms.Button btnUpdateStatus;
private System.Windows.Forms.TextBox txtBoxRFID;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel7;
private System.Windows.Forms.GroupBox groupBox4;
private System.Windows.Forms.DataGridView dgvLineMission;
private System.Windows.Forms.DataGridViewTextBoxColumn Column24;
private System.Windows.Forms.DataGridViewTextBoxColumn Column8;
private System.Windows.Forms.GroupBox groupBox8;
private System.Windows.Forms.Label lblCharge4;
private System.Windows.Forms.Label lblCharge3;
private System.Windows.Forms.Label lblStandy2;
private System.Windows.Forms.Label lblStandy1;
private System.Windows.Forms.TextBox txtBoxLineName;
private System.Windows.Forms.Label label8;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.Button btnReSendTask;
private System.Windows.Forms.DataGridViewTextBoxColumn Column1;
private System.Windows.Forms.DataGridViewTextBoxColumn Column2;
private System.Windows.Forms.DataGridViewTextBoxColumn Column4;
private System.Windows.Forms.DataGridViewTextBoxColumn Column14;
private System.Windows.Forms.DataGridViewTextBoxColumn Column21;
private System.Windows.Forms.DataGridViewTextBoxColumn Column3;
private System.Windows.Forms.DataGridViewTextBoxColumn Column18;
private System.Windows.Forms.DataGridViewTextBoxColumn Column23;
private System.Windows.Forms.DataGridViewTextBoxColumn Column13;
private System.Windows.Forms.DataGridViewTextBoxColumn Column19;
private System.Windows.Forms.DataGridViewButtonColumn Column11;
}
}
using BLL;
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AGVControl
{
public partial class FrmMain : Form
{
private bool exit = false;
private bool change;
private NotifyIcon notify;
private ContextMenuStrip notifyMenu;
private System.Timers.Timer showTimer;
private Label[] agvRunInfo;
//private string[] agvRunStep;
public FrmMain()
{
InitializeComponent();
showTimer = new System.Timers.Timer();
showTimer.Interval = 5000;
//showTimer.Enabled = true;
//showTimer.AutoReset = true;
showTimer.Elapsed += ShowTimer_Elapsed;
showTimer.Start();
Common.logTextBox = TxtLog;
agvRunInfo = new Label[] { label1, label2, label3, label4, label5, label6 };
}
private void ShowConfig()
{
int n;
//agvRunStep = new string[Common.agvInfo.Count];
for (int i = 0; i < Common.agvInfo.Count; i++)
{
Common.mir.Get_IO_Status(Common.agvInfo[i], out bool[] input, out bool[] output);
if (input != null && input.Length == 4)
Common.agvInfo[i].IsExistShelf = input[3];
n = DgvAgv.Rows.Add(Common.agvInfo[i].ToRow());
DgvAgv.Rows[n].HeaderCell.Value = (n + 1).ToString();
if (i % 2 == 0)
DgvAgv.Rows[n].DefaultCellStyle.BackColor = Color.LightBlue;
if (!Common.agvInfo[i].IsCon)
DgvAgv.Rows[n].DefaultCellStyle.ForeColor = Color.Red;
//agvRunStep[i] = Common.agvInfo[i].Msg;
//if (i % 2 == 0)
// agvRunInfo[i].BackColor = Color.LightBlue;
//else
// agvRunInfo[i].BackColor = Color.LightGray;
}
cmbBoxLineName.Items.Add("产线名称");
foreach (var item in Common.nodeInfo)
{
if (item.Name.StartsWith("A"))
continue;
cmbBoxLineName.Items.Add(item.AliceName);
}
cmbBoxLineName.SelectedIndex = 0;
for (int i = 0; i < Common.nodeInfo.Count; i++)
{
n = DgvNode.Rows.Add(Common.nodeInfo[i].ToRow());
DgvNode.Rows[n].HeaderCell.Value = (n + 1).ToString();
if (i % 2 == 0)
DgvNode.Rows[n].DefaultCellStyle.BackColor = Color.LightBlue;
if (!Common.nodeInfo[i].Online)
DgvNode.Rows[n].DefaultCellStyle.ForeColor = Color.Red;
}
LstAgvPlace.Items.Clear();
LstAgvPlace.Items.AddRange(Common.showNameMissionName.Keys.ToArray());
LstAgvPlace.SelectedIndex = 0;
}
private void Server_NodeChanged(int nodeIndex)
{
Invoke(new Action(() =>
{
DgvNode.Rows[nodeIndex].DefaultCellStyle.ForeColor = Common.nodeInfo[nodeIndex].Online && Common.nodeInfo[nodeIndex].IsUse ? Color.Black : Color.Red;
DgvNode.Rows[nodeIndex].SetValues(Common.nodeInfo[nodeIndex].ToRow());
}));
System.GC.Collect();
}
private void Server_NodeOnline(int nodeIndex)
{
Invoke(new Action(() =>
{
DgvNode.Rows[nodeIndex].DefaultCellStyle.ForeColor = Common.nodeInfo[nodeIndex].Online ? Color.Black : Color.Red;
DgvNode.Rows[nodeIndex].SetValues(Common.nodeInfo[nodeIndex].ToRow());
}));
System.GC.Collect();
}
/// <summary>
/// 小车状态刷新
/// </summary>
/// <param name="agvIndex"></param>
private void Control_AgvChanged(int agvIndex)
{
Invoke(new Action(() => { DgvAgv.Rows[agvIndex].DefaultCellStyle.ForeColor = Common.agvInfo[agvIndex].StateID.Equals(eAGVState.Error) ? Color.Red : Color.Black; }));
Invoke(new Action(() =>
{
DgvAgv.Rows[agvIndex].SetValues(Common.agvInfo[agvIndex].ToRow());
}));
System.GC.Collect();
}
private void MissionManager_MissionChanged()
{
ShowEmptyTask();
}
private void Control_AgvOnline(int agvIndex)
{
Invoke(new Action(() => { DgvAgv.Rows[agvIndex].DefaultCellStyle.ForeColor = Common.agvInfo[agvIndex].IsCon ? Color.Black : Color.Red; }));
Invoke(new Action(() =>
{
DgvAgv.Rows[agvIndex].SetValues(Common.agvInfo[agvIndex].ToRow());
}));
GC.Collect();
}
private void ItemShow_Click(object sender, EventArgs e)
{
Show();
if (WindowState == FormWindowState.Minimized)
WindowState = FormWindowState.Normal;
}
private void ItemExit_Click(object sender, EventArgs e)
{
foreach (var item in Common.agvInfo)
{
Common.WriteIni(item.Name, SettingString.RFID, item.RFID);
}
notify.Dispose();
exit = true;
Close();
}
private void Notify_MouseDoubleClick(object sender, MouseEventArgs e)
{
Show();
if (WindowState == FormWindowState.Minimized)
WindowState = FormWindowState.Normal;
}
private void FrmMain_Load(object sender, EventArgs e)
{
//托盘菜单
notifyMenu = new ContextMenuStrip();
ToolStripMenuItem itemShow = new ToolStripMenuItem("显示(&S)");
itemShow.Click += ItemShow_Click;
ToolStripMenuItem itemExit = new ToolStripMenuItem("退出(&X)");
itemExit.Click += ItemExit_Click;
notifyMenu.Items.Add(itemShow);
notifyMenu.Items.Add(itemExit);
//托盘控件
notify = new NotifyIcon { Icon = Icon, Visible = true, ContextMenuStrip = notifyMenu, Text = Text };
notify.MouseDoubleClick += Notify_MouseDoubleClick;
ShowConfig();
change = true;
//ChkAutoCharge.Checked = Common.chargeStatus.AutoCharge;
change = false;
Common.control.AgvChanged += Control_AgvChanged;
Common.control.AgvOnline += Control_AgvOnline;
Common.server.NodeChanged += Server_NodeChanged;
Common.server.NodeOnline += Server_NodeOnline;
Common.missionManager.MissionChanged += MissionManager_MissionChanged;
//foreach (var item in Common.agvInfo)
//{
// cmbBoxAGVName.Items.Add(item.Name);
//}
//cmbBoxAGVName.Items.Add("None");
//cmbBoxAGVName.SelectedIndex = Common.agvInfo.Count;
}
private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
{
if (!exit)
{
e.Cancel = true;
Hide();
}
foreach (var item in Common.agvInfo)
{
Common.WriteIni(item.Name, SettingString.RFID, item.RFID);
}
//showTimer.Enabled = false;
showTimer.Stop();
Common.control.AgvChanged -= Control_AgvChanged;
Common.control.AgvOnline -= Control_AgvOnline;
Common.server.NodeChanged -= Server_NodeChanged;
Common.server.NodeOnline -= Server_NodeOnline;
}
private void DgvAgv_CellClick(object sender, DataGridViewCellEventArgs e)
{
DgvAgv.Refresh();
if (e.RowIndex == -1) return;
if (e.ColumnIndex == 10) //调用
{
if (Common.agvInfo[e.RowIndex].IsUse.Equals(true))
{
Common.chargeStatus.ClearRandomChargeInfo(Common.agvInfo[e.RowIndex]);
Common.agvInfo[e.RowIndex].IsUse = false;
Common.agvInfo[e.RowIndex].CurJob = null;
//Common.agvInfo[e.RowIndex].RFID = "";
// }
}
else
{
//清除4c临时待机位的占用
if (Common.agvInfo[e.RowIndex].Name.Equals(Common.StandbyStation.C4_Station1))
{
Common.StandbyStation.C4_Station1 = "";
}
else if (Common.agvInfo[e.RowIndex].Name.Equals(Common.StandbyStation.C4_Station2))
{
Common.StandbyStation.C4_Station2 = "";
}
Common.LogInfo(string.Format("手动开启小车自动模式,并清除上一次的自动模式的运行信息{0} {1}", Common.agvInfo[e.RowIndex].Name, Common.agvInfo[e.RowIndex].RunInfo()));
//Common.agvInfo[e.RowIndex].CurJob = null;
Common.agvInfo[e.RowIndex].RFID = "";
// Common.agvInfo[e.RowIndex].Place = "";
Common.agvInfo[e.RowIndex].IsUse = true;
// }
//else
//{
// Common.agvInfo[e.RowIndex].IsUse = true;
// Common.LogInfo(string.Format("手动开启小车自动模式,并继续上一次的自动模式的运行信息{0} {1}", Common.agvInfo[e.RowIndex].Name, Common.agvInfo[e.RowIndex].RunInfo()));
//}
}
DgvAgv.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = Common.agvInfo[e.RowIndex].IsUse.ToString();
Common.WriteIni(Common.agvInfo[e.RowIndex].Name, SettingString.IsUse, Common.agvInfo[e.RowIndex].IsUse.ToString());
Common.appConfig.Save();
DgvAgv.Rows[e.RowIndex].SetValues(Common.agvInfo[e.RowIndex].ToRow());
}
}
private void DgvNode_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex == -1) return;
if (e.ColumnIndex == 7) //调用
{
Common.nodeInfo[e.RowIndex].IsUse = !Common.nodeInfo[e.RowIndex].IsUse;
DgvNode.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = Common.nodeInfo[e.RowIndex].IsUse.ToString();
Common.WriteIni(Common.nodeInfo[e.RowIndex].Name, SettingString.IsUse, Common.nodeInfo[e.RowIndex].IsUse.ToString());
Common.appConfig.Save();
DgvNode.Rows[e.RowIndex].SetValues(Common.nodeInfo[e.RowIndex].ToRow());
}
else if (e.ColumnIndex == 8) //清除缓存
{
//清除节点缓存
Common.LogInfo(string.Format("手动清除缓存,{0} {1}", Common.nodeInfo[e.RowIndex].AgvName, Common.nodeInfo[e.RowIndex].Name));
string name = Common.nodeInfo[e.RowIndex].AgvName;
Common.nodeInfo[e.RowIndex].AgvName = "";
DgvNode.Rows[e.RowIndex].Cells[5].Value = "";
Common.nodeInfo[e.RowIndex].RFID = "";
DgvNode.Rows[e.RowIndex].Cells[4].Value = "";
//清除小车缓存
int idx = Common.agvInfo.FindIndex(s => s.Name == name);
if (idx > -1)
{
Common.agvInfo[idx].Place = "";
Common.agvInfo[idx].RFID = "";
DgvAgv.Rows[idx].SetValues(Common.agvInfo[idx].ToRow());
//添加Init任务
Common.mir.Add_Mission_Fleet(Common.agvInfo[idx], Common.agvMission["Init"]);
Common.mir.State_Ready(Common.agvInfo[idx]);
}
DgvNode.Rows[e.RowIndex].SetValues(Common.nodeInfo[e.RowIndex].ToRow());
}
}
private void BtnMissionReady_Click(object sender, EventArgs e)
{
if (DgvAgv.SelectedCells.Count == 0) return;
int idx = DgvAgv.SelectedCells[0].RowIndex;
if (idx < 0) return;
if (Common.agvInfo[idx].IsCon)
Common.mir.State_Ready(Common.agvInfo[idx]);
}
private void BtnMissionPause_Click(object sender, EventArgs e)
{
if (DgvAgv.SelectedCells.Count == 0) return;
int idx = DgvAgv.SelectedCells[0].RowIndex;
if (idx < 0) return;
if (Common.agvInfo[idx].IsCon)
Common.mir.State_Pause(Common.agvInfo[idx]);
Common.LogInfo("手动暂停:[" + Common.agvInfo[idx].Name + "]");
}
private void BtnMissionAdd_Click(object sender, EventArgs e)
{
if (DgvAgv.SelectedCells.Count == 0) return;
int idx = DgvAgv.SelectedCells[0].RowIndex;
if (idx < 0) return;
if (Common.agvInfo[idx].IsCon)
{
if (!Common.agvInfo[idx].IsUse)
//{
// if (MessageBox.Show("确定在自动模式下对小车手动分配任务?", Common.agvInfo[idx].Name, MessageBoxButtons.YesNo) == DialogResult.No)
// return;
// Common.agvInfo[idx].Resend();
// //Common.agvInfo[idx].TaskSend = LstAgvPlace.Text;
// Common.LogInfo("手动添加任务:[" + Common.agvInfo[idx].Name + "][" + Common.agvInfo[idx].CurTaskName + "]");
//}
//else
{
bool rtn = Common.mir.Add_Mission_Fleet(Common.agvInfo[idx], Common.agvMission[Common.showNameMissionName[LstAgvPlace.Text]]);
if (!rtn)
return;
if (LstAgvPlace.Text.StartsWith("Move"))
Common.agvInfo[idx].Place = LstAgvPlace.Text.Substring(4);
Common.LogInfo("手动添加任务:[" + Common.agvInfo[idx].Name + "][" + Common.agvInfo[idx].CurTaskName + "]");
}
////清除4c临时待机位的占用
//if (Common.agvInfo[idx].Name.Equals(Common.StandbyStation.C4_Station1))
//{
// Common.StandbyStation.C4_Station1 = "";
//}
//else if (Common.agvInfo[idx].Name.Equals(Common.StandbyStation.C4_Station2))
//{
// Common.StandbyStation.C4_Station2 = "";
//}
DgvAgv.Rows[idx].SetValues(Common.agvInfo[idx].ToRow());
}
}
private void BtnClearError_Click(object sender, EventArgs e)
{
if (DgvAgv.SelectedCells.Count == 0) return;
int idx = DgvAgv.SelectedCells[0].RowIndex;
if (idx < 0) return;
if (Common.agvInfo[idx].IsCon)
Common.mir.Clear_Error(Common.agvInfo[idx]);
Common.LogInfo("手动清除错误:[" + Common.agvInfo[idx].Name + "]");
}
bool InShhow = false;
private void ShowTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
//ShowEmptyTask();
if (InShhow)
return;
InShhow = true;
Invoke(new Action(() =>
{
for (int i = 0; i < Common.agvInfo.Count; i++)
{
try
{
agvRunInfo[i].Text = Common.agvInfo[i].RunInfo();
Application.DoEvents();
}
catch (Exception ex)
{
Common.log.Error("显示"+ Common.agvInfo[i].Name+"运行信息异常");
}
}
if (!Common.doubleLine_WO.Equals(""))
lblWO.Text = Common.doubleLine_WO;
if (!AGVManager.A6_Target.Equals(""))
lblDestInfo.Text = AGVManager.A6_Target;
lblCharge3.Text = "充电桩3:" + Common.chargeStatus.charge3;
lblCharge4.Text = "充电桩6:" + Common.chargeStatus.charge6;
lblStandy1.Text = "4C待机位1:" + Common.StandbyStation.C4_Station1;
lblStandy2.Text = "4C待机位2:" + Common.StandbyStation.C4_Station2;
}));
InShhow = false;
}
private void ShowEmptyTask()
{
if (dgvLineMission.InvokeRequired)
{
dgvLineMission.Invoke(new Action(() => ShowEmptyTask()));
return;
}
try
{
if (dgvLineMission.Rows.Count != 0)
dgvLineMission.Rows.Clear();
foreach (var item in Common.missionManager.missionList)
{
var key = Common.nodeInfo.Where(q => q.Name == item.NodeName).Select(q => q.AliceName);
if (key.ToList().Count > 0)
dgvLineMission.Rows.Add(item.CreateTime, key.ToList()[0]);
}
groupBox4.Text = "产线解绑信息:共" + Common.missionManager.EmptyMissionCount.ToString() + "个";
}
catch (Exception ex)
{
Common.log.Error(ex);
}
}
private void ChkAutoCharge_CheckedChanged(object sender, EventArgs e)
{
if (change) return;
//Common.chargeStatus.AutoCharge = ChkAutoCharge.Checked;
}
private void btnDeleteMission_Click(object sender, EventArgs e)
{
try
{
if (cmbBoxLineName.SelectedItem == null || cmbBoxLineName.SelectedIndex == 0)
{
return;
}
if (MessageBox.Show("确定删除产线任务[" + cmbBoxLineName.SelectedItem.ToString() + "]", "手动删除解绑任务", MessageBoxButtons.YesNo) == DialogResult.No)
return;
//int idx=Common.missionList.FindIndex(s => s.NodeName == Common.agvProductionLine[txtBoxMission.Text]);
int idx = Common.nodeInfo.FindIndex(s => s.AliceName.Equals(cmbBoxLineName.SelectedItem.ToString()));
if (idx > -1)
{
if (Common.DelEmptyShelfTask(Common.nodeInfo[idx].Name))
{
Common.LogInfo("手动删除任务成功:" + cmbBoxLineName.SelectedItem.ToString());
}
else
{
Common.LogInfo("手动删除任务失败");
}
}
}
catch (Exception ex)
{
Common.log.Error("手动删除任务失败:" + ex.Message);
}
}
private void btnAddMission_Click(object sender, EventArgs e)
{
try
{
if (cmbBoxLineName.SelectedItem == null || cmbBoxLineName.SelectedIndex == 0)
{
return;
}
if (cmbBoxLineName.SelectedItem.ToString().StartsWith("A"))
return;
if (MessageBox.Show("确定添加产线任务[" + cmbBoxLineName.SelectedItem.ToString() + "]", "手动1添加解绑", MessageBoxButtons.YesNo) == DialogResult.No)
return;
int idx = Common.nodeInfo.FindIndex(s => s.AliceName.Equals(cmbBoxLineName.SelectedItem.ToString()));
if (idx > -1)
{
if (Common.AddEmptyShelfTask(Common.nodeInfo[idx].Name))
{
Common.LogInfo("手动添加任务成功:" + cmbBoxLineName.SelectedItem.ToString());
}
else
{
Common.LogInfo("手动添加任务失败");
}
}
}
catch (Exception ex)
{
ShowEmptyTask();
Common.log.Error("手动添加任务失败:" + ex.Message);
}
}
private void button1_Click(object sender, EventArgs e)
{
if (DgvAgv.SelectedCells.Count == 0) return;
int idx = DgvAgv.SelectedCells[0].RowIndex;
if (idx < 0) return;
if (Common.agvInfo[idx].IsCon)
{
Common.agvInfo[idx].IsExistShelf = !Common.agvInfo[idx].IsExistShelf;
Common.LogInfo("手动设置 " + Common.agvInfo[idx].Name + " 负载状态=" + Common.agvInfo[idx].IsExistShelf);
}
}
private void button1_Click_1(object sender, EventArgs e)
{
if (DgvAgv.SelectedCells.Count == 0) return;
int idx = DgvAgv.SelectedCells[0].RowIndex;
if (idx < 0) return;
if (Common.agvInfo[idx].IsCon)
{
Common.agvInfo[idx].CurJob = new ChargeJob("");
return;
//Common.agvInfo[idx].TaskSend = LstAgvPlace.Text;
}
}
private void button2_Click(object sender, EventArgs e)
{
if (DgvAgv.SelectedCells.Count == 0) return;
int idx = DgvAgv.SelectedCells[0].RowIndex;
if (idx < 0) return;
if (Common.agvInfo[idx].IsCon)
{
Common.agvInfo[idx].CurJob = new EmptyAGVBackJob("");
return;
}
}
private void btnWO_Click(object sender, EventArgs e)
{
try
{
Task.Factory.StartNew(new Action(() =>
{
if (AGVManager.FindCurSO(out AGVManager.WOData woData))
{
if (Common.GetNodeNameByLineName(woData.line, out string loc))
{
Common.doubleLine_WO = "工单料信息:" + woData.ToTxt(loc);
Common.LogInfo(Common.doubleLine_WO);
}
}
}));
}
catch (Exception ex)
{
MessageBox.Show("查询失败:" + ex.Message + "\r\n" + ex.StackTrace);
}
}
/// <summary>
/// 出料查询
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button5_Click(object sender, EventArgs e)
{
try
{
Task.Factory.StartNew(() =>
{
int idx = Common.nodeInfo.FindIndex(s => s.Name.Equals(SettingString.A6));
if (idx > -1)
{
AGVManager.FindFullShelfTarget(Common.nodeInfo[idx].RFID, out AGVManager.BoxDestInfo FullShelfDestInfo);
}
});
}
catch (Exception ex)
{
MessageBox.Show("查询失败:" + ex.Message + "\r\n" + ex.StackTrace);
}
}
private void button9_Click(object sender, EventArgs e)
{
if (DgvAgv.SelectedCells.Count == 0) return;
int idx = DgvAgv.SelectedCells[0].RowIndex;
if (idx < 0) return;
if (Common.agvInfo[idx].IsCon)
{
Common.agvInfo[idx].CurJob = null;
}
}
private void button1_Click_2(object sender, EventArgs e)
{
if (DgvAgv.SelectedCells.Count == 0) return;
int idx = DgvAgv.SelectedCells[0].RowIndex;
if (idx < 0) return;
Common.CalculateNearNode(Common.agvInfo[idx], SettingString.D4_Name_Prefix);
}
private void btnUpdateStatus_Click(object sender, EventArgs e)
{
try
{
Task.Factory.StartNew(() =>
{
AGVManager.UpdateStatus(txtBoxRFID.Text.ToUpper(), txtBoxLineName.Text.ToUpper());
Common.LogInfo(string.Format("手动上报状态 产线{0} 物料状态更新成功[{1}]", txtBoxLineName.Text.ToUpper(), txtBoxRFID.Text.ToUpper()));
});
}
catch (Exception ex)
{
MessageBox.Show("手动上报状态失败:" + ex.Message + "\r\n" + ex.StackTrace);
}
}
private void dgvLineMission_Click(object sender, EventArgs e)
{
ShowEmptyTask();
}
private void btnClearC4StandyInfo_Click(object sender, EventArgs e)
{
Common.StandbyStation.C4_Station1 = "";
Common.StandbyStation.C4_Station2 = "";
}
private void btnReSendTask_Click(object sender, EventArgs e)
{
if (DgvAgv.SelectedCells.Count == 0) return;
int idx = DgvAgv.SelectedCells[0].RowIndex;
if (idx < 0) return;
if (Common.agvInfo[idx].IsCon)
{
if (Common.agvInfo[idx].IsUse)
{
if (MessageBox.Show("确定在自动模式下对小车重发任务?", Common.agvInfo[idx].Name, MessageBoxButtons.YesNo) == DialogResult.No)
return;
Common.agvInfo[idx].Resend();
Common.mir.State_Ready(Common.agvInfo[idx]);
//Common.agvInfo[idx].TaskSend = LstAgvPlace.Text;
Common.LogInfo("手动重发任务:[" + Common.agvInfo[idx].Name + "][" + Common.agvInfo[idx].CurTaskName + "]");
}
////清除4c临时待机位的占用
//if (Common.agvInfo[idx].Name.Equals(Common.StandbyStation.C4_Station1))
//{
// Common.StandbyStation.C4_Station1 = "";
//}
//else if (Common.agvInfo[idx].Name.Equals(Common.StandbyStation.C4_Station2))
//{
// Common.StandbyStation.C4_Station2 = "";
//}
DgvAgv.Rows[idx].SetValues(Common.agvInfo[idx].ToRow());
}
}
}
}
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="Column1.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column2.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column4.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column14.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column21.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column3.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column18.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column23.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column13.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column19.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column11.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column6.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column12.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column22.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column7.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column10.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column9.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column5.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column16.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column24.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column8.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAgHEAAAEAIAA46QAAFgAAACgAAACAAAAA4gAAAAEAIAAAAAAAAOIAAGEPAABhDwAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAwAAAEAAAACEAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAA
AI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAA
AI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAABqAAAAEHFKLAD7pGIAYkAmAAAAACwAAACAAAAAjwAA
AI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAA
AI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAA
AI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAA
AI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAACPAAAAjwAA
AI8AAACPAAAAjwAAAI8AAACPAAAAjwAAAI8AAABvAAAAHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAA7gAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8IBQN8/75yDP+yaw1rRiobAQEBvwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAADCAAAAIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAFQAAANAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/1s7I+v7pGLI/aVjx9yPVs8fFAz6AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAB9AAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtAAAA7AAAAP8AAAD/EwsG/yMV
DP8jFAz/IxQM/yMUDP8jFAz/IxQM/yMUDP8jEwv/IxIK/yMSCv8jEgr/IxIK/xcMB/8AAAD/AAAA/wEB
AP8aEQr/JBcO/yMXDv8jFw7/IxcO/yMXDv8jFw7/IxcO/yMXDv8jFw7/IxcO/yMXDv8jFw7/IxcO/yIX
Df8/KRn/xoJN//2lY//7pGL/+aNh/5JfOf8qHBH/IxcO/yMXDv8jFw7/IxcO/yMXDv8jFw7/IxcO/yMX
Dv8jFw7/IxcO/yMXDv8jFw7/IxcO/yMXDv8jFw7/IxcO/yMXDv8jFw7/IxcO/yMXDv8jFw7/IxcO/yMX
Dv8jFw7/IxcO/yMXDv8jFw7/IxcO/yMXDv8jFw7/IxcO/yMXDv8jFw7/IxcO/yMXDv8jFw7/IxcO/yMX
Dv8jFw7/IxcO/yMXDv8jFw7/IxcO/yMXDv8jFw7/IxcO/yMXDv8jFw7/IxcO/yMXDv8jFw7/IxcO/yMX
Dv8jFw7/IxcO/yMXDv8jFw7/IxcO/yMXDv8jFw7/IxcO/yMXDf8jFQz/IxQM/yMUDP8jFQz/IRML/wcE
Av8AAAD/AAAA/wAAAKEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAC8AAADuAAAA/wAAAP92RSf/4oRL/9+DSv/fg0r/34NK/9+DSv/fg0r/34NK/958
R//ec0H/3nNB/95zQf/idUL/kUwr/wEBAP8AAAD/BgQC/6FpP//klVn/4JNY/+CTWP/gk1j/4JNY/+CT
WP/gk1j/4JNY/+CTWP/gk1j/4JNY/+CTWP/gk1j/4ZNY/+2bXf/8pWL/+6Ri//ukYv/7pGL/+qNi/+aX
Wv/gklj/4JNY/+CTWP/gk1j/4JNY/+CTWP/gk1j/4JNY/+CTWP/gk1j/4JNY/+CTWP/gk1j/4JNY/+CT
WP/gk1j/4JNY/+CTWP/gk1j/4JNY/+CTWP/gk1j/4JNY/+CTWP/gk1j/4JNY/+CTWP/gk1j/4JNY/+CT
WP/gk1j/4JNY/+CTWP/gk1j/4JNY/+CTWP/gk1j/4JNY/+CTWP/gk1j/4JNY/+CTWP/gk1j/4JNY/+CT
WP/gk1j/4JNY/+CTWP/gk1j/4JNY/+CTWP/gk1j/4JNY/+CTWP/gk1j/4JNY/+CTWP/gk1j/4JNY/+CT
WP/gk1j/4JFW/9+ETP/fgkr/34NK/9+DSv/QekX/KxkO/wAAAP8AAAD/AAAAoQAAAAEAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALwAAAO4AAAD/AAAA/4RO
LP/+lVX/+5NU//uTVP/7k1T/+5NU//uTVP/7k1T/+oxP//qCSf/6gkn/+oJJ//6ES/+kVTD/AQEA/wAA
AP8HBAP/tXZH//+oZP/9pWP//aVj//2lY//9pWP//aVj//2lY//9pWP//aVj//2lY//9pWP//aVj//2l
Y//9pWP//KVi//ukYv/7pGL/+6Ri//ukYv/7pGL//KVj//2lY//9pWP//aVj//2lY//9pWP//aVj//2l
Y//9pWP//aVj//2lY//9pWP//aVj//2lY//9pWP//aVj//2lY//9pWP//aVj//2lY//9pWP//aVj//2l
Y//9pWP//aVj//2lY//9pWP//aVj//2lY//9pWP//aVj//2lY//9pWP//aVj//2lY//9pWP//aVj//2l
Y//9pWP//aVj//2lY//9pWP//aVj//2lY//9pWP//aVj//2lY//9pWP//aVj//2lY//9pWP//aVj//2l
Y//9pWP//aVj//2lY//9pWP//aVj//2lY//9pWP//aVj//2lY//8o2H/+5VV//uTU//7k1T//JRU/+qJ
Tv8wHBD/AAAA/wAAAP8AAAChAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAvAAAA7gAAAP8AAAD/g00s//yUVP/5klP/+ZJT//mSU//5klP/+ZJT//mS
U//5i0//+IFJ//iBSf/4gUn//INK/6NVMP8BAQD/AAAA/wcEA/+zdUb//6dk//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//uiYP/5lFX/+ZJT//mSU//6k1P/6YhO/y8cEP8AAAD/AAAA/wAAAKEAAAABAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8AAADuAAAA/wAA
AP+DTSz//JRU//mSU//5klP/+ZJT//mSU//5klP/+ZJT//mLT//4gUn/+IFJ//iBSf/8g0r/o1Uw/wEB
AP8AAAD/BwQD/7N1Rv//p2T/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Jg//mUVf/5klP/+ZJT//qT
U//piE7/LxwQ/wAAAP8AAAD/AAAAoQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAALwAAAO4AAAD/AAAA/4NNLP/8lFT/+ZJT//mSU//5klP/+ZJT//mS
U//5klP/+YtP//iBSf/4gUn/+IFJ//yDSv+jVTD/AQEA/wAAAP8HBAP/s3VG//+nZP/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7omD/+ZRV//mSU//5klP/+pNT/+mITv8vHBD/AAAA/wAAAP8AAAChAAAAAQAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvAAAA7gAA
AP8AAAD/g00s//yUVP/5klP/+ZJT//mSU//5klP/+ZJT//mSU//5i0//+IFJ//iBSf/4gUn//INK/6NV
MP8BAQD/AAAA/wcEA/+zdUb//6dk//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uiYP/5lFX/+ZJT//mS
U//6k1P/6YhO/y8cEP8AAAD/AAAA/wAAAKEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8AAADuAAAA/wAAAP+DTSz//JRU//mSU//5klP/+ZJT//mS
U//5klP/+ZJT//mLT//4gUn/+IFJ//iBSf/8g0r/o1Uw/wEBAP8AAAD/BwQD/7N1Rv//p2T/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Jg//mUVf/5klP/+ZJT//qTU//piE7/LxwQ/wAAAP8AAAD/AAAAoQAA
AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALwAA
AO4AAAD/AAAA/4NNLP/8lFT/+ZJT//mSU//5klP/+ZJT//mSU//5klP/+YtP//iBSf/4gUn/+IFJ//yD
Sv+jVTD/AQEA/wAAAP8HBAP/s3VG//+nZP/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7omD/+ZRV//mS
U//5klP/+pNT/+mITv8vHBD/AAAA/wAAAP8AAAChAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvAAAA7gAAAP8AAAD/g00s//yUVP/5klP/+ZJT//mS
U//5klP/+ZJT//mSU//5i0//+IFJ//iBSf/4gUn//INK/6NVMP8BAQD/AAAA/wcEA/+zdUb//6dk//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uiYP/5lFX/+ZJT//mSU//6k1P/6YhO/y8cEP8AAAD/AAAA/wAA
AKEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AC8AAADuAAAA/wAAAP+DTSz//JRU//mSU//5klP/+ZJT//mSU//5klP/+ZJT//mLT//4gUn/+IFJ//iB
Sf/8g0r/o1Uw/wEBAP8AAAD/BwQD/7N1Rv//p2T/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Jg//mU
Vf/5klP/+ZJT//qTU//piE7/LxwQ/wAAAP8AAAD/AAAAoQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALwAAAO4AAAD/AAAA/4NNLP/8lFT/+ZJT//mS
U//5klP/+ZJT//mSU//5klP/+YtP//iBSf/4gUn/+IFJ//yDSv+jVTD/AQEA/wAAAP8HBAP/s3VG//+n
ZP/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7omD/+ZRV//mSU//5klP/+pNT/+mITv8vHBD/AAAA/wAA
AP8AAAChAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAvAAAA7gAAAP8AAAD/g00s//yUVP/5klP/+ZJT//mSU//5klP/+ZJT//mSU//5i0//+IFJ//iB
Sf/4gUn//INK/6NVMP8BAQD/AAAA/wcEA/+zdUb//6dk//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ui
YP/5lFX/+ZJT//mSU//6k1P/6YhO/y8cEP8AAAD/AAAA/wAAAKEAAAABAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8AAADuAAAA/wAAAP+DTSz//JRU//mS
U//5klP/+ZJT//mSU//5klP/+ZJT//mLT//4gUn/+IFJ//iBSf/8g0r/o1Uw/wEBAP8AAAD/BwQD/7N1
Rv//p2T/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Jg//mUVf/5klP/+ZJT//qTU//piE7/LxwQ/wAA
AP8AAAD/AAAAoQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAALwAAAO4AAAD/AAAA/4NNLP/8lFT/+ZJT//mSU//5klP/+ZJT//mSU//5klP/+YtP//iB
Sf/4gUn/+IFJ//yDSv+jVTD/AQEA/wAAAP8HBAP/s3VG//+nZP/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7omD/+ZRV//mSU//5klP/+pNT/+mITv8vHBD/AAAA/wAAAP8AAAChAAAAAQAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvAAAA7gAAAP8AAAD/g00s//yU
VP/5klP/+ZJT//mSU//5klP/+ZJT//mSU//5i0//+IFJ//iBSf/4gUn//INK/6NVMP8BAQD/AAAA/wcE
A/+zdUb//6dk//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uiYP/5lFX/+ZJT//mSU//6k1P/6YhO/y8c
EP8AAAD/AAAA/wAAAKEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAC8AAADuAAAA/wAAAP+DTSz//JRU//mSU//5klP/+ZJT//mSU//5klP/+ZJT//mL
T//4gUn/+IFJ//iBSf/8g0r/o1Uw/wEBAP8AAAD/BwQD/7N1Rv//p2T/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//ukYv/7pGL/+6Ri//uk
Yv/7pGL/+6Jg//mUVf/5klP/+ZJT//qTU//piE7/LxwQ/wAAAP8AAAD/AAAAoQAAAAEAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALwAAAO4AAAD/AAAA/4NN
LP/8lFT/+ZJT//mSU//5klP/+ZJT//mSU//5klP/+YtP//iBSf/4gUn/+IFJ//yDSv+jVTD/AQEA/wAA
AP8HBQP/tXZH//+oZP/9pmP//aZj//2mY//9pmP//aZj//2mY//9pmP//aZj//2mY//9pmP//aZj//2m
Y//9pmP//aZj//2mY//9pmP//aZj//2mY//9pmP//aZj//2mY//9pmP//aZj//2mY//9pmP//aZj//2m
Y//9pmP//aZj//2mY//9pmP//aZj//2mY//9pmP//aZj//2mY//9pmP//aZj//2mY//9pmP//aZj//2m
Y//9pmP//aZj//2mY//9pmP//aZj//2mY//9pmP//aZj//2mY//9pmP//aZj//2mY//9pmP//aZj//2m
Y//9pmP//aZj//2mY//9pmP//aZj//2mY//9pmP//aZj//2mY//9pmP//aZj//2mY//9pmP//aZj//2m
Y//9pmP//aZj//2mY//9pmP//aZj//2mY//9pmP//aZj//2mY//9o2H//JZW//uTVP/7k1T//ZRU/+yL
T/8wHBD/AAAA/wAAAP8AAAChAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAvAAAA7gAAAP8AAAD/g00s//yUVP/5klP/+ZJT//mSU//5klP/+ZJT//mS
U//5i0//+IFJ//iBSf/4gUn//INK/6NVMP8BAQD/AAAA/wQCAf9WOCL/eE8v/3ZNLv92TS7/dk0u/3ZN
Lv92TS7/dk0u/3ZNLv92TS7/dk0u/3ZNLv92TS7/dk0u/3ZNLv92TS7/dk0u/3ZNLv92TS7/dk0u/3ZN
Lv92TS7/dk0u/3ZNLv92TS7/dk0u/3ZNLv92TS7/dk0u/3ZNLv92TS7/dk0u/3ZNLv92TS7/dk0u/3ZN
Lv92TS7/dk0u/3ZNLv92TS7/dk0u/3ZNLv92TS7/dk0u/3ZNLv92TS7/dk0u/3ZNLv92TS7/dk0u/3ZN
Lv92TS7/dk0u/3ZNLv92TS7/dk0u/3ZNLv92TS7/dk0u/3ZNLv92TS7/dk0u/3ZNLv92TS7/dk0u/3ZN
Lv92TS7/dk0u/3ZNLv92TS7/dk0u/3ZNLv92TS7/dk0u/3ZNLv92TS7/dk0u/3ZNLv92TS7/dk0u/3ZN
Lv92TS7/dk0u/3ZMLf92Rij/dkUn/3VFJ/97SCn/hE0s/x8SCv8AAAD/AAAA/wAAAKEAAAABAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8AAADuAAAA/wAA
AP+DTSz//JRU//mSU//5klP/+ZJT//mSU//5klP/+ZJT//mLT//4gUn/+IFJ//iBSf/8g0r/o1Uw/wEB
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAALwAAAO4AAAD/AAAA/4RNLP/8lFT/+ZJT//mSU//5klP/+ZJT//mS
U//5klP/+YtP//iBSf/4gUn/+IFJ//yDSv+jVTD/AQEA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADKAAAAJQAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAA6wAA
AP8AAAD/fUkq//yUVP/5klP/+ZJT//mSU//5klP/+ZJT//mSU//5i0//+IFJ//iBSf/4gUn//INK/6FU
L/8BAAD/AAAA/wEBAf8TEA7/GRYT/xkVE/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkV
E/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkV
E/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkV
E/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkV
E/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkV
E/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkVE/8ZFRP/GRUT/xkVE/8ZFRL/GRQQ/xkT
D/8XEg7/CggG/wAAAP8AAAD/AAAA/wAAAP8AAADDAAAAIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAADcAAAA/wAAAP9fNyD/+ZJT//mSU//5klP/+ZJT//mS
U//5klP/+ZJT//iJTv/4gUn/+IFJ//iBSf/8g0r/h0Yo/wAAAP8AAAD/DAoJ/6qSgP/cvaX/2bqj/9m6
o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6
o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6
o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6
o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6
o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6
o//ZuqP/2bqj/9m6o//ZuqP/2bqj/9m6o//ZtJf/2KyI/9aqhv+5k3T/alRD/xMPDP8AAAD/AAAA/wAA
AP8AAAClAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAA
AL0AAAD/AAAA/yoZDv/gg0v/+5NU//mSU//5klP/+ZJT//mSU//5kVP/+IZM//iBSf/4gUn/+YFJ//B9
R/9JJhX/AAAA/wAAAP8kHxv/48Kq///dwf//28D//9vA///bwP//28D//9vA///bwP//28D//9vA///b
wP//28D//9vA///bwP//28D//9vA///bwP//28D//9vA///bwP//28D//9vA///bwP//28D//9vA///b
wP//28D//9vA///bwP//28D//9vA///bwP//28D//9vA///bwP//28D//9vA///bwP//28D//9vA///b
wP//28D//9vA///bwP//28D//9vA///bwP//28D//9vA///bwP//28D//9vA///bwP//28D//9vA///b
wP//28D//9vA///bwP//28D//9vA///bwP//28D//9vA///bwP//28D//9vA///bwP//28D//9vA///b
wP//28D//9vA///bwP//28D//9vA///bwP//28D//9vA///bwP//28D//9vA///bwP//28D//9vA///a
vv//0Kv//sqf///LoP/7x57/s45x/yIbFf8AAAD/AAAA/wAAAPgAAABWAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAP8AAAD/AgEB/4tRLv/7k1T/+ZJT//mS
U//5klP/+ZJT//mOUf/4gkr/+IFJ//iBSf/8g0r/rloz/wwGBP8AAAD/AAAA/1lNQ//51rv//dm+//3Z
vv/92b7//tq///7av//92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//7a
v//+2r///dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//tq///3Z
vv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//7av//+2r7//dm+//3Z
vv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/+2r///tq///3Zvv/92b7//dm+//3Z
vv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//tq///7av//92b7//dm+//3Zvv/92b7//dm+//3Z
vv/92b7//dm+//3Zvv/92b7//dm+//7avv/+2r///dm///3WuP/8yqH//Mie//zInv//y6D/rYls/w4L
Cf8AAAD/AAAA/wAAALQAAAAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAvAAAA5gAAAP8AAAD/Gg8J/7ZqPf/8lFT/+pNT//mSU//5klP/+IdN//iBSf/5gUn//INK/81q
PP8vGA7/AAAA/wAAAP8JCAf/sJeE///cwf/92b7//dm+//7av//uzLP/7cuy//7av//92b7//dm+//3Z
vv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/+2r//8tC2/+nIr//82L3//dm+//3Zvv/92b7//dm+//3Z
vv/92b7//dm+//3Zvv/92b7//tq///fUuv/nxq7/+da7//7av//92b7//dm+//3Zvv/92b7//dm+//3Z
vv/92b7//dm+//7avv/717z/6Meu//XSuP/+2r///dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Z
vv/92b7//dm+/+vJsP/wzrT//tq///3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//7a
v//vzbT/7Mqx//7Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/+2r//9NG3/+jH
rv/72L3//tm+//zOqf/8yJ7//Mie//3Inv/3xJv/V0U3/wAAAP8AAAD/AAAA5gAAACcAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAACEAAAA/wAAAP8AAAD/HhIK/5pb
M//si0///JRU//2NUP/8hEv//INK//F9R/+vWzT/LxkO/wAAAP8AAAD/AAAA/1VJQP/00bf//tq///3Z
vv//28D/vqOP/zsyLP83Lyn/tZuI///av//92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//9u//9m6
o/9OQzv/LCYh/5WAcP/72L3//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//7av//syrH/Z1hN/ygj
Hv90Y1f/8tC2//7av//92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7/+NW6/4ZzZf8qJB//WU1D/+PD
qv//2r///dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//7avv+mjn3/MSol/0I5Mv/Lrpj//9vA//3Z
vv/92b7//dm+//3Zvv/92b7//dm+//3Zvv//28D/xamU/z82L/80LCf/rpWD//7av//92b7//dm+//3Z
vv/92b7//dm+//3Zvv/92b7//9q//96/p/9USD//KyQg/415av/61rz//dKw//zInv/8yJ7//Mie///L
of+dfWP/AQEB/wAAAP8AAADvAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAABYAAAC3AAAA/wAAAP8AAAD/BwQC/0AlFf+DSyv/plcx/6dXMf+MSSn/TCgW/w0H
BP8AAAD/AAAA/wAAAP8sJiH/07Wf///bwP/92b7//dm+//rWvP9VSUD/AAAA/wAAAP9MQTn/99S6//3Z
vv/92b7//dm+//3Zvv/92b7//dm+//3Zvv//3MH/h3Rl/wAAAP8AAAD/JB8b/+PDq///2r///dm+//3Z
vv/92b7//dm+//3Zvv/92b7//9zB/7OZhv8EBAP/AAAA/wwKCf/FqZT//9zA//3Zvv/92b7//dm+//3Z
vv/92b7//dm+///bwP/WuKH/FxMR/wAAAP8AAAD/m4V1///dwf/92b7//dm+//3Zvv/92b7//dm+//3Z
vv/+2r//8M61/zoxK/8AAAD/AAAA/2tcUP/+2r///dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//zZ
vv9fUkj/AAAA/wAAAP9CODH/9NG3//7Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv//3MH/k35u/wAA
AP8AAAD/HBgV/9y9pv//1bT//Mie//zInv/8yJ7//8ug/76Wd/8KCAb/AAAA/wAAAO4AAAAvAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEEAAADzAAAA/wAA
AP8AAAD/AAAA/wAAAP8CAQH/AgEB/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/5WAcP//3cH//dm+//3Z
vv/92b7//dm+/3NjVv8AAAD/AAAA/2dZTv/717z//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+///c
wf+giXj/BQQE/wAAAP8+NS//7cuy//7av//92b7//dm+//3Zvv/92b7//dm+//3Zvv//3MD/xqqV/xQR
D/8AAAD/IBsY/9W3oP//28D//dm+//3Zvv/92b7//dm+//3Zvv/92b7//9q//+PDqv8vKCP/AAAA/wsJ
CP+ymYb//9zB//3Zvv/92b7//dm+//3Zvv/92b7//dm+//7Zvv/207n/VUlA/wAAAP8AAAD/h3Rm///b
wP/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//tq//31rXv8AAAD/AAAA/15QRv/51bv//dm+//3Z
vv/92b7//dm+//3Zvv/92b7//dm+///cwf+qkoD/CAcG/wAAAP81Lij/58eu//7Us//8yJ7//Mie//zI
nv//y6D/tpBy/wcGBf8AAAD/AAAA7gAAAC8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAANQAAAO8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8BAQD/pI17///dwf/92b7//dm+//3Zvv/+2r//5sWs/4l2Z/+FcmT/4cGp//7a
v//92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//tq///PQtv+ahHT/emlc/8+xm//+2r///dm+//3Z
vv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/61rv/r5aD/3ZlWf+5n4v//Ni9//3Zvv/92b7//dm+//3Z
vv/92b7//dm+//3Zvv/92b7//tm+/8WplP93Zlr/pI17//fTuf/92b7//dm+//3Zvv/92b7//dm+//3Z
vv/92b7//dm+//7av//ZuqP/gG1g/5B8bP/syrH//tq///3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Z
vv/+2r//6civ/415av+CcGL/3b6m//7av//92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//tq+//XS
uP+fiXj/eGda/8mtl//+2r///dCu//zInv/8yJ7//Mie///LoP+Ha1X/AAAA/wAAAP8AAADuAAAALwAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2AAAA8AAA
AP8AAAD/KyIb/yohGv8NCgj/BgUE/wYFBP8LCQf/IxwW/zktJP8FBAP/AAAA/wEAAP+ji3r//93B//3Z
vv/92b7//dm+//3Zvv/+2r///9zA///bwP//2r///dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Z
vv/92b7//tq////cwP//28D//9vA//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Z
vv//3MD//9vA///bwP/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//9vA///b
wP//3MD//tm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+///bv///28D//9zA//7a
v//92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/+2r///9zA///bwP//2r///dm+//3Z
vv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//tq+///cwP//28D//9vA//3YvP/8zKb//Mie//zI
nv/+yp//57eR/zcrIv8AAAD/AAAA/wAAANkAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADYAAADwAAAA/wAAAP+Lblf/6LiR/8Sce/+zjnD/so1v/8CY
eP/hs43/uJJ0/woIBv8AAAD/AQAA/6KLev//3cH//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Z
vv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Z
vv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Z
vv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Z
vv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Z
vv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Zvv/92b7//dm+//3Z
vv/92b7//dm+//3Zvv/92b7//dOz//zJn//8yJ7//8qg//bDmv91XUr/AQEB/wAAAP8AAAD/AAAAkwAA
AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANgAA
APAAAAD/AAAA/45xWf//zaL//8ug///LoP//y6D//8ug///Mof++lnf/CggG/wAAAP8AAAD/pY18///h
xf//3cH//93B///dwf//3cH//93B///dwf//3cH//93B///dwf//3cH//93B///dwf//3cH//93B///d
wf//3MH//tq+//3Zvv/92b7//dm+//7av///3cH//93B///dwf//3cH//93B///dwf//3cH//93B///d
wf//3cH//93B///dwf//3cH//93B///dwf//3cH//93B///dwf//3cH//93B///dwf//3cH//93B///d
wf//3cH//93B///dwf//3cH//93B///dwf//3cH//93B///dwf//3cH//93B///dwf//3cH//93B///d
wf//3cH//93B///dwf//3cH//93B///dwf//3cH//93B///dwf//3cH//93B///dwf//3cH//93B///d
wf//3cH//93B///dwf//3cH//93B///dwf//3cH//93B///dwf//3cH//93C///avP//z6f//8ug//3I
nv/cr4r/bldF/wcFBP8AAAD/AAAA/wAAAOQAAAAyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2AAAA8AAAAP8AAAD/jnFZ///Lof/8yJ7//Mie//zI
nv/8yJ7//8ug/72Wd/8KCAb/AAAA/wAAAP9dUEb/lH9v/5J9bf+SfW3/kn1t/5J9bf+SfW3/kn1t/5J9
bf+SfW3/kn1t/5J9bf+SfW3/kn1t/5J9bf+SfW3/kn1u/7Sah//00bf//tq///3Zvv/+2r//6Meu/6aO
fP+RfG3/kn1t/5J9bf+SfW3/kn1t/5J9bf+SfW3/kn1t/5J9bf+SfW3/kn1t/5J9bf+SfW3/kn1t/5J9
bf+SfW3/kn1t/5J9bf+SfW3/kn1t/5J9bf+SfW3/kn1t/5J9bf+SfW3/kn1t/5J9bf+SfW3/kn1t/5J9
bf+SfW3/kn1t/5J9bf+SfW3/kn1t/5J9bf+SfW3/kn1t/5J9bf+SfW3/kn1t/5J9bf+SfW3/kn1t/5J9
bf+SfW3/kn1t/5J9bf+SfW3/kn1t/5J9bf+SfW3/kn1t/5J9bf+SfW3/kn1t/5J9bf+SfW3/kn1t/5J9
bf+SfW3/kn1t/5J9bf+SfW3/kXdi/5FzW/+OcFn/aFNB/yYeGP8AAAD/AAAA/wAAAP8AAAD5AAAAbgAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
ADYAAADwAAAA/wAAAP+OcVn//8uh//zInv/8yJ7//Mie//zInv//y6D/vZZ3/woIBv8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/CAcG/456a///2r///tm+//bTuf9fUUf/AQEB/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA9wAAAIMAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANgAAAPAAAAD/AAAA/45xWf//y6H//Mie//zI
nv/8yJ7//Mie///LoP+9lnf/CggG/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/LykkzvrWvHb/3MB11LafgBMR
D+cAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAANoAAABkAAAABgAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAA2AAAA8AAAAP8AAAD/jnFZ///Lof/8yJ7//Mie//zInv/8yJ7//8ug/72Wd/8KCAb/AAAA/wAA
AP8AAAD1AAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAA
APAAAADwAAAA8AAAAN8AAABSoYp5AOrJsAD///8AAAAAfQAAAOoAAADwAAAA8AAAAPAAAADwAAAA8AAA
APAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAA
APAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAA
APAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAA
APAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAA
APAAAADuAAAA5AAAAMEAAAB6AAAAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADYAAADwAAAA/wAAAP+OcVn//8uh//zI
nv/8yJ7//Mie//zInv//y6D/vZZ3/woIBv8AAAD/AAAA/wAAAH4AAAAzAAAANgAAADYAAAA2AAAANgAA
ADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAAIgAAAAEAAAAAAAAAAAAA
AAAAAAAHAAAAKwAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAA
ADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAA
ADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAA
ADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAA
ADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAADIAAAAkAAAADAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAANgAAAPAAAAD/AAAA/45xWf//y6H//Mie//zInv/8yJ7//Mie///LoP+9lnf/CggG/wAA
AP8AAAD/AAAAWgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2AAAA8AAAAP8AAAD/jnFZ///L
of/8yJ7//Mie//zInv/8yJ7//8ug/72Wd/8KCAb/AAAA/wAAAP8AAABcAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAADYAAADwAAAA/wAAAP+OcVn//8uh//zInv/8yJ7//Mie//zInv//y6D/vZZ3/woI
Bv8AAAD/AAAA/wAAAFwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANgAAAPAAAAD/AAAA/45x
Wf//y6H//Mie//zInv/8yJ7//Mie///LoP+9lnf/CggG/wAAAP8AAAD/AAAAXAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAA2AAAA8AAAAP8AAAD/jnFZ///Lof/8yJ7//Mie//zInv/8yJ7//8ug/72W
d/8KCAb/AAAA/wAAAP8AAABcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADYAAADwAAAA/wAA
AP+OcVn//8uh//zInv/8yJ7//Mie//zInv//y6D/vZZ3/woIBv8AAAD/AAAA/wAAAFwAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAANgAAAPAAAAD/AAAA/45xWf//y6H//Mie//zInv/8yJ7//Mie///L
oP+9lnf/CggG/wAAAP8AAAD/AAAAXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2AAAA8AAA
AP8AAAD/jnFZ///Lof/8yJ7//Mie//zInv/8yJ7//8ug/72Wd/8KCAb/AAAA/wAAAP8AAABcAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADYAAADwAAAA/wAAAP+OcVn//8uh//zInv/8yJ7//Mie//zI
nv//y6D/vZZ3/woIBv8AAAD/AAAA/wAAAFwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAcAAAAvAAAAIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANgAA
APAAAAD/AAAA/45xWf//y6H//Mie//zInv/8yJ7//Mie///LoP+9lnf/CggG/wAAAP8AAAD/AAAAXAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAfQAAAO4AAADaAAAAQgAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2AAAA8AAAAP8AAAD/jnFZ///Lof/8yJ7//Mie//zI
nv/8yJ7//8ug/72Wd/8KCAb/AAAA/wAAAP8AAABcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAC4AAADnAAAA/wAAAP8AAACPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
ADYAAADwAAAA/wAAAP+OcVn//8uh//zInv/8yJ7//Mie//zInv//y6D/vZZ3/woIBv8AAAD/AAAA/wAA
AFwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhQAAAP8AAAD/AAAA/AAA
AGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANgAAAPAAAAD/AAAA/45xWf//y6H//Mie//zI
nv/8yJ7//Mie///LoP+9lnf/CggG/wAAAP8AAAD/AAAAXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAB8AAADXAAAA/wAAAP8AAADRAAAAGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAIAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAA2AAAA8AAAAP8AAAD/jnFZ///Lof/8yJ7//Mie//zInv/8yJ7//8ug/72Wd/8KCAb/AAAA/wAA
AP8AAABcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVwAAAP0AAAD/AAAA/wAA
AIsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWQAAALwAAACTAAAAFgAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADYAAADwAAAA/wAAAP+OcVn//8uh//zI
nv/8yJ7//Mie//zInv//y6D/vZZ3/woIBv8AAAD/AAAA/wAAAFwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAABDAAAA8wAAAP8AAAD/AAAAvQAAABEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
ACgAAADhAAAA/wAAAP8AAABnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAANgAAAPAAAAD/AAAA/45xWf//zKH//Mie//zInv/8yJ7//Mie///LoP++lnf/CggG/wAA
AP8AAAD/AAAAXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAACnAAAA/wAA
AP8AAAD8AAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfAAAAP8AAAD/AAAA/gAAAGIAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAA7QAAAP8AAAD/fWNP///M
of/8yJ7//Mie//zInv/8yJ7//8yh/6aEaP8EAwL/AAAA/wAAAP0AAABXAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAADqAAAA/wAAAP8AAADSAAAAHAAAAAAAAAALAAAAJAAA
AFMAAADZAAAA/wAAAP8AAADXAAAAHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAABkAAADXAAAA/wAAAP8pIRr/xp18//nGnP/7x53/+8ed//rGnf/ZrIj/QjQp/wAA
AP8AAAD/AAAA7gAAADQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA
AI4AAAD/AAAA/wAAAP4AAACmAAAAjgAAAMAAAADjAAAA+QAAAP8AAAD/AAAA/wAAAIQAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAI0AAAD/AAAA/wAA
AP8cFhL/UUAz/15LO/9eSzv/VkQ2/ycfGP8AAAD/AAAA/wAAAP8AAACyAAAACgAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJgAAANoAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAADmAAAALQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAKwAAAOIAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA9AAAAEkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAlQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADxAAAA0gAAAGcAAAACAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABTAAAA8wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD8AAAAbwAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8AAADRAAAA/wAAAP8AAAD9AAAA6AAA
AMYAAACYAAAAZgAAADgAAAAWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAALsAAAD/AAAA/wkEAv88Gw//LxYM/ygSCv8oEgr/LBQL/zwc
EP8PBwT/AAAA/wAAAP8AAADTAAAAGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAhQAAAP8AAAD/AAAA/wAAAJ0AAAAoAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0AAAA7gAA
AP8AAAD/WSkX/+prPf/maTz/42g7/+NoO//laTv/7W09/3M1Hv8AAAD/AAAA/wAAAPkAAABOAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADUAAADnAAAA/wAAAP8AAADaAAAAJQAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFUAAAD8AAAA/wQCAf+mTCv//HNB//hxQP/4ckD/+HJA//hy
QP/7c0H/v1gy/w0GA/8AAAD/AAAA/wAAAHUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAHAAAApQAAAP8AAAD/AAAA/QAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXQAA
AP4AAAD/BwMC/7dUL//7c0H/93FA//dxQP/3cUD/93FA//pyQf/PXzb/FgoG/wAAAP8AAAD/AAAAgwAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAD1AAAA/wAAAP8AAADCAAAAEwAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABNAAAA+gAAAP8BAAD/k0Mm//tzQf/3cUD/93FA//dx
QP/3cUD/+3NB/65QLf8HAwL/AAAA/wAAAP8AAABoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAATAAAAwQAAAP8AAAD/AAAA9QAAAFEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
ACYAAADjAAAA/wAAAP83GQ7/3GU5//tzQf/4cUD/+HFA//tzQf/pazz/TSMU/wAAAP8AAAD/AAAA9wAA
AE8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAIAAAALAAAAEwAAABPAAAAMAAAAHYAAAD9AAAA/wAAAP8AAACmAAAABwAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAJ4AAAD/AAAA/wAAAP9IIRP/wFgy/+pr
Pf/sbD3/yFs0/1opF/8DAQH/AAAA/wAAAP8AAAD+AAAA1wAAAH4AAAAXAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAARQAAALEAAADpAAAA+gAA
APsAAADtAAAA8gAAAP8AAAD/AAAA5gAAADUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAMgAAAOEAAAD/AAAA/wAAAP8SCAX/NxkO/zsbD/8WCgb/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAALoAAAAjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAgAAAGoAAADtAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAACfAAAAAgAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVwAAAOkAAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8FBAP/AAAA/wAAAP8AAAD/AAAA/wAAAKkAAAALAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABKAAAA7wAAAP8AAAD/AAAA/wIC
Af8DAwL/AAAA/wAAAP8AAAD/AAAA/wAAAOUAAABRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAARQAAAMEAAAD5AAAA/wAAAP8AAAD/AAAA/wICAf81KiH/jG9Y/6+L
bv97Yk3/GRQQ/wAAAP8AAAD/AAAA+QAAAFoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAEAAAAL8AAAD/AAAA/wIBAf9IOS3/oH9k/6iFaf9iTj3/Ew8M/wAAAP8AAAD/AAAA/wAA
ANoAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAA
AHAAAAD3AAAA/wAAAP8UEA3/i25X/+e3kf//y6D//8uh///KoP+riGv/DgsJ/wAAAP8AAAD/AAAAwgAA
ABEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABeAAAA+gAAAP8AAAD/Tz4x/+q6
k///zKH//8uh//nGnP/Dm3r/SDkt/wAAAP8AAAD/AAAA/wAAAIYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXAAAAP0AAAD/AQEB/4hsVf/+yqD//smf//zI
nv/8yJ7//cme//jFnP9dSjr/AAAA/wAAAP8AAAD7AAAAYQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAEwAAAMUAAAD/AAAA/xIOC//BmXn//8ug//zInv/8yJ7//Mie///Lof/dr4r/LCMc/wAA
AP8AAAD/AAAAyAAAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAB/AAAA/wAAAP8VEQ3/0qaD///KoP/8yJ7//Mie//zInv/8yJ7//8ug/8Sce/8UEA3/AAAA/wAA
AP8AAADIAAAAFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABlAAAA/AAAAP8AAAD/Y08+//nF
nP/8yJ7//Mie//zInv/8yJ7//Mie//7Kn/9sVkT/AAAA/wAAAP8AAADgAAAAHgAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH0AAAD/AAAA/xMPDP/MooD//8qg//zI
nv/8yJ7//Mie//zInv/8yJ7/+sac/2dSQf8AAAD/AAAA/wAAAP0AAABpAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAGAAAAMwAAAD/AAAA/xcSDv/Jn37//8qg//zInv/8yJ7//Mie//zInv/8yJ7//Mie/2ZR
QP8AAAD/AAAA/wAAAN8AAAAeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAWQAAAPwAAAD/AAAA/4FnUf/+yZ///Mie//zInv/8yJ7//Mie//zInv//yqD/zKKA/xkU
EP8AAAD/AAAA/wAAAM8AAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABvAAAA/gAAAP8AAAD/bFZE//rH
nf/8yJ7//Mie//zInv/8yJ7//Mie//7Kn//arYn/JR4X/wAAAP8AAAD/AAAAwgAAAA0AAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAA2gAAAP8AAAD/IxwW/9ir
h//+yp///Mie//zInv/8yJ7//Mie//zInv/7x53/b1hG/wAAAP8AAAD/AAAA/wAAAHQAAAAAAAAAAAAA
AAAAAAAAAAAAHQAAANMAAAD/AAAA/xoVEf/PpIH//8qg//zInv/8yJ7//Mie//zInv/8yJ7//cmf/31j
Tv8AAAD/AAAA/wAAAP8AAAB7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAB+AAAA/wAAAP8AAAD/eWBM//3Jnv/8yJ7//Mie//zInv/8yJ7//Mie///K
oP/RpoP/HBcS/wAAAP8AAAD/AAAA1gAAAB8AAAAAAAAAAAAAAAAAAAB3AAAA/wAAAP8AAAD/c1tI//zI
nv/8yJ7//Mie//zInv/8yJ7//Mie//7KoP/WqYb/IRoU/wAAAP8AAAD/AAAA2gAAACMAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEAAADYAAAA/wAA
AP8eGBP/06iE///KoP/8yJ7//Mie//zInv/8yJ7//Mie//zInv93Xkv/AAAA/wAAAP8AAAD/AAAAewAA
AAAAAAAAAAAAIQAAANgAAAD/AAAA/yAZFP/UqIX//8qg//zInv/8yJ7//Mie//zInv/8yJ7//Mie/3Ze
Sv8AAAD/AAAA/wAAAP8AAAB5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHUAAAD/AAAA/wAAAP9yW0j//Mie//zInv/8yJ7//Mie//zI
nv/8yJ7//sqf/9erh/8jHBb/AAAA/wAAAP8AAADaAAAAJAAAAAAAAAB/AAAA/wAAAP8AAAD/fWNO//3J
n//8yJ7//Mie//zInv/8yJ7//Mie///KoP/QpYL/HBYS/wAAAP8AAAD/AAAA0wAAAB0AAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGwAA
ANAAAAD/AAAA/xoVEP/No4H//8qg//zInv/8yJ7//Mie//zInv/8yJ7//cmf/4FmUf8AAAD/AAAA/wAA
AP8AAACBAAAAJwAAAN4AAAD/AAAA/yYeGP/arYn//sqf//zInv/8yJ7//Mie//zInv/8yJ7/+8ed/21X
RP8AAAD/AAAA/wAAAP4AAABvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAawAAAP0AAAD/AAAA/2lTQv/6xp3//Mie//zI
nv/8yJ7//Mie//zInv/+yp//3a+K/yggGf8AAAD/AAAA/wAAAN8AAACsAAAA/wAAAP8AAAD/hWpT//7K
n//8yJ7//Mie//zInv/8yJ7//Mie///KoP/Jn37/FxIO/wAAAP8AAAD/AAAAzQAAABgAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAWAAAAygAAAP8AAAD/FBAN/8WdfP//yqD//Mie//zInv/8yJ7//Mie//zInv/+yp//iWxW/wAA
AP8AAAD/AAAA/wAAAP4AAAD/AAAA/yoiG//fsYz//sqf//zInv/8yJ7//Mie//zInv/8yJ7/+cac/2NP
Pv8AAAD/AAAA/wAAAP0AAABoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkAAAA/AAAAP8AAAD/YEw8//jF
nP/8yJ7//Mie//zInv/8yJ7//Mie//7Jn//hs43/LSQc/wAAAP8AAAD/AAAA/wAAAP8BAQH/jXBY///K
oP/8yJ7//Mie//zInv/8yJ7//Mie///LoP/Dm3r/Ew8M/wAAAP8AAAD/AAAAxwAAABQAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAABMAAADEAAAA/wAAAP8RDgv/wJh4///LoP/8yJ7//Mie//zInv/8yJ7//Mie///K
oP+Rc1v/AgIB/wAAAP8AAAD/AAAA/zIoH//ktY///smf//zInv/8yJ7//Mie//zInv/8yJ7/98Sb/11K
Ov8AAAD/AAAA/wAAAPoAAABfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFsAAAD5AAAA/wAA
AP9ZRzj/9sOa//3Inv/8yJ7//Mie//zInv/8yJ7//smf/+a2kP8yKCD/AAAA/wAAAP8CAgH/lHZd///L
oP/8yJ7//Mie//zInv/8yJ7//Mie///LoP+8lXb/DwwK/wAAAP8AAAD/AAAAvwAAABAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAALsAAAD/AAAA/w4LCf+4knP//8ug//zInv/8yJ7//Mie//zI
nv//yqD//Mie/2JOPf8AAAD/AAAA/xENCv/In37//82i//3Jn//8yJ7//Mie//zInv/9yZ7/9MKZ/1RC
NP8AAAD/AAAA/wAAAPgAAABWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUwAA
APcAAAD/AAAA/08/Mv/zwZj//cme//zInv/9yZ7//Mie/8adfP9oUkH/GhQQ/wAAAP8AAAD/BAMD/z4x
J/+XeF//67qT//7Kn//8yJ7//Mie///LoP+zjnD/CwkH/wAAAP8AAAD/AAAAuAAAAAwAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAAtQAAAP8AAAD/CggG/7CMbv//zKH//cmf//fE
m/+Pclr/FxIP/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wICAf9IOS3/06iE//7KoP/9yZ//88GY/0w8
L/8AAAD/AAAA/wAAAPYAAABPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAABMAAAA9AAAAP8AAAD/Oi4k/9irh//9yZ7/j3FZ/wgHBf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP85LST/266K//nGnP+Pclr/BwYE/wAAAP8AAAD/AAAAsQAAAAoAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAACrAAAA/wAAAP8AAAD/LCMc/2RP
P/8VEQ3/AAAA/wAAAP8CAQH/ORoP/3o4IP+GPSP/XysY/xUKBv8AAAD/AAAA/wAAAP9ENiv/VUQ1/wwJ
B/8AAAD/AAAA/wAAAPIAAABGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAADUAAADfAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AwEB/24yHP/laTv/+nNB//tz
Qf/2cUD/t1Qw/yYRCv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAjwAAAAUAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAADWAAAA/wAA
AP8AAAD/AAAA/wAAAP89HBD/5mk8//lyQf/3cUD/93FA//dxQP/7c0H/nUgp/wYDAf8AAAD/AAAA/wAA
AP8AAAD/AAAA9wAAAJYAAAARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACYAAACIAAAA1QAAAP4AAAD/AAAA/4E7If/7c0H/93FA//dx
QP/3cUD/93FA//lyQP/cZTn/Ig8J/wAAAP8AAAD/AAAA8AAAALIAAABVAAAACAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAABGAAAA9AAAAP8AAAD/kEIl//tzQf/3cUD/93FA//dxQP/3cUD/+HJA/+RoO/8qEwv/AAAA/wAA
AP8AAACrAAAACQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACoAAADpAAAA/wAAAP9qMBv/+HJA//dx
QP/3cUD/93FA//dxQP/6ckH/y101/xYKBv8AAAD/AAAA/wAAAI8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAADwAAAMUAAAD/AAAA/xwNB//CWTL//HNB//lyQP/4cUD/+nJB//JvP/9pMBv/AAAA/wAA
AP8AAAD9AAAAXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcwAAAP8AAAD/AAAA/y0V
DP+mTCv/4Gc6/+dqPP/OXjX/azEc/wcDAv8AAAD/AAAA/wAAANIAAAAbAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAYAAAAwQAAAP8AAAD/AAAA/wgEAv8nEgr/MRYN/xgLBv8AAAD/AAAA/wAA
AP8AAAD3AAAAYgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAAAAzwAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+AAAAIIAAAAGAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAowAAAPAAAAD/AAAA/wAAAP8AAAD/AAAA/QAA
ANQAAABkAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAHAAAAPQAAAH4AAACjAAAAqwAAAJQAAABgAAAAHQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAEAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAA////////////////////////////////////////////////////////
/////////gAAAAAcAAAAAAAAAAAD//gAAAAAAAAAAAAAAAAAAP/wAAAAAAAAAAAAAAAAAAB/8AAAAAAA
AAAAAAAAAAAAf/AAAAAAAAAAAAAAAAAAAH/wAAAAAAAAAAAAAAAAAAB/8AAAAAAAAAAAAAAAAAAAf/AA
AAAAAAAAAAAAAAAAAH/wAAAAAAAAAAAAAAAAAAB/8AAAAAAAAAAAAAAAAAAAf/AAAAAAAAAAAAAAAAAA
AH/wAAAAAAAAAAAAAAAAAAB/8AAAAAAAAAAAAAAAAAAAf/AAAAAAAAAAAAAAAAAAAH/wAAAAAAAAAAAA
AAAAAAB/8AAAAAAAAAAAAAAAAAAAf/AAAAAAAAAAAAAAAAAAAH/wAAAAAAAAAAAAAAAAAAB/8AAAAAAA
AAAAAAAAAAAAf/AAAAAAAAAAAAAAAAAAAH/wAAAAAAAAAAAAAAAAAAB/8AAAAAAAAAAAAAAAAAAAf/AA
AAAAAAAAAAAAAAAAAH/wAAAAAAAAAAAAAAAAAAB/8AAAAAAAAAAAAAAAAAAAP/AAAAAAAAAAAAAAAAAA
AB/wAAAAAAAAAAAAAAAAAAAf8AAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAA
AAAAAAAP8AAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAA/4AAAAAAAAAAAAAAAAAAAP+AAAAAAA
AAAAAAAAAAAAD/wAAAAAAAAAAAAAAAAAAA/+AAAAAAAAAAAAAAAAAAAP/gAAAAAAAAAAAAAAAAAAD/4A
AAAAAAAAAAAAAAAAAA/+AAAAAAAAAAAAAAAAAAAP/gAAAAAAAAAAAAAAAAAAH/4AAAAAAAAAAAAAAAAA
AD/+AAAAAAAAAAAAAAAAAAA//gAAAAAAAAAAAAAAAAAA//4AAAAAAAAAAAAAAAAAAf/+AAB/////////
/////////gAAf/////////////////4AAH/////////////////+AAB//////////////////gAAf///
//////////////4AAH/////////////////+AAB///8B/////////////gAAf///AP////////////4A
AH///gD////////////+AAB///4A/////////////gAAf//+AOB///////////4AAH///gDAf///////
///+AAB///4BwD///////////gAAf//+AIA///////////4AAH///gAAP//////////+AAB///4AAD//
/////////gAAf//+AAB///////////4AAH///wAAf//////////+AAB///8AAP///////////gAAf///
AAD///////////4AAH///gAB///////////+AAB///4AB////////////gAAf//8AH////////////4A
AH///AD////////////+AAAf/wAA/////////////gAAD/4AAf////////////4AAAf8AAP/////////
///+AAAH+AAD/////////////gAAA/gAA/////////////8AAAPwAAH/////////////gAAB8AAB////
/////////8AAAeAAAf/////////////gAADgAAH/////////////4AAAwAAB/////////////+AAAAAA
Af/////////////gAAAAAAH/////////////8AAAAAAB//////////////AAAAAAA//////////////4
AAAAAAP/////////////+AAAAAAD//////////////wAAAAAB//////////////8AAAAAA//////////
/////gAAAAAP//////////////4AAAAAH///////////////AAAAAB///////////////wAAAAA/////
//////////+AAAAAP///////////////gAAAAH///////////////8AAAAB////////////////AAAAA
////////////////4AAAAP///////////////+AAAAH////////////////wAAAB////////////////
+AAAA/////////////////wAAA//////////////////AAAf/////////////////wAAH///////////
//////8AAD//////////////////AAA//////////////////4AAf//////////////////AAP//////
////////////4AH///////////////////wH////////////////////////////////////////////
//////////////////////////////////8=
</value>
</data>
</root>
\ No newline at end of file \ No newline at end of file
using BLL;
using log4net.Config;
using log4net.Util.TypeConverters;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AGVControl
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.ThreadException += Application_ThreadException;
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
XmlConfigurator.Configure();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//程序只能运行一次
Process current = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName(current.ProcessName);
foreach (Process process in processes)
{
if (process.Id == current.Id) continue; //自己
if (process.MainModule.FileName == current.MainModule.FileName)
{
//显示已打开的程序
API.ShowWindow(process.MainWindowHandle, API.SW_RESTORE);
API.SwitchToThisWindow(process.MainWindowHandle, true);
return;
}
}
//Common.logTextBox = new TextBox();
//Common.missionView = new DataGridView();
Common.missionManager = new MissionManager();
Common.log = log4net.LogManager.GetLogger("AgvServer");
Common.log.Info("=====程序开始=====");
ReadConfig();
Common.ReadLinePlace();
Common.mir = new MiR_API();
Common.control = new BLL.Control();
//获取节点位置
Common.GetNodesPosition();
Common.control.Start();
Common.server = new AgvServer();
Common.server.Start();
Common.web = new WebService();
Common.web.Open(Common.appConfig.AppSettings.Settings["WebService"].Value);
Application.Run(new FrmMain());
Common.control.Stop();
Common.server.Stop();
Common.web.Close();
Common.log.Info("=====程序结束=====\r\n");
}
private static void ReadConfig()
{
string path;
string[] line;
string[] temp;
bool isuse;
string rfid = "";
Common.appConfig = System.Configuration.ConfigurationManager.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.None);
Common.agvInfo = new List<Agv_Info>();
path = Common.CONFIG_PATH + SettingString.FileName_AGV;
line = System.IO.File.ReadAllLines(path, Encoding.UTF8);
for (int i = 1; i < line.Length; i++)
{
temp = line[i].Split(',');
if (temp.Length != 5) continue;
//string val = Common.appConfig.AppSettings.Settings[temp[1]].Value;
bool.TryParse(Common.ReadIni(temp[1], SettingString.IsUse), out isuse); //Convert.ToBoolean(val.Split(',')[0]);
rfid = Common.ReadIni(temp[1], SettingString.RFID); //val.Split(',')[1];
Common.agvInfo.Add(new Agv_Info(temp[0], temp[1], temp[2], temp[3], temp[4], isuse, rfid));
}
Common.agvMission = new Dictionary<string, string>();
Common.showNameMissionName = new Dictionary<string, string>();
path = Common.CONFIG_PATH + SettingString.FileName_AgvMission;
line = System.IO.File.ReadAllLines(path, Encoding.UTF8);
for (int i = 1; i < line.Length; i++)
{
temp = line[i].Split(',');
if (temp.Length != 3) continue;
Common.agvMission.Add(temp[1], temp[2]);
Common.showNameMissionName.Add(temp[0], temp[1]);
}
Common.nodeInfo = new List<ClientNode>();
path = Common.CONFIG_PATH + SettingString.FileName_AgvProductionLine;
line = System.IO.File.ReadAllLines(path, Encoding.GetEncoding("gb2312"));
for (int i = 1; i < line.Length; i++)
{
temp = line[i].Split(',');
if (temp.Length != 6) continue;
Boolean.TryParse(Common.ReadIni(temp[1], SettingString.IsUse), out bool isUse);
Int32.TryParse(Common.ReadIni(temp[1], SettingString.EmptyShelfCnt), out int emptyShelfCnt);
if (temp[1].Equals("A5"))
{
Common.nodeInfo.Add(new DoubleLineNodeFor4C(temp[1], temp[2], temp[3], temp[0], temp[4], temp[5], isUse, emptyShelfCnt));
}
else if (temp[1].Equals("A6"))
{
Common.nodeInfo.Add(new DoubleLineNodeFor4D(temp[1], temp[2], temp[3], temp[0], temp[4], temp[5], isUse, emptyShelfCnt));
}
else
Common.nodeInfo.Add(new ClientNode(temp[1], temp[2], temp[3], temp[0], temp[4], temp[5], isUse, emptyShelfCnt));
}
Common.chargeStatus = new ChargeStatus();
Common.itsHttp = Common.appConfig.AppSettings.Settings["ITS"].Value;
}
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Common.log.Error("CurrentDomain_UnhandledException", (Exception)e.ExceptionObject);
}
private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
Common.log.Error("Application_ThreadException", e.Exception);
}
}
}
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("AGVControl-ProductionLine")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AGVControl-ProductionLine")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("e1c3207d-c67d-4b46-a9db-d182f2074ccb")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace AGV_3D_Line.Properties {
using System;
/// <summary>
/// 一个强类型的资源类,用于查找本地化的字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.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 (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AGV_3D_Line.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 重写当前线程的 CurrentUICulture 属性
/// 重写当前线程的 CurrentUICulture 属性。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}
<?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>
\ No newline at end of file \ No newline at end of file
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace AGV_3D_Line.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.7.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;
}
}
}
}
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>
文件属性发生变化
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AGVControl
{
public class Agv_Info
{
/// <summary>
/// 小车名称
/// </summary>
public string Name { private set; get; }
/// <summary>
/// 小车在FLEET中的ID号
/// </summary>
public string ID { private set; get; }
/// <summary>
/// IP地址
/// </summary>
public string IP { private set; get; }
/// <summary>
/// IO模块GUID
/// </summary>
public string IOID { private set; get; }
/// <summary>
/// 授权码
/// </summary>
public string Authorization { private set; get; }
/// <summary>
/// 当前架子的RFID
/// </summary>
public string RFID { set; get; }
/// <summary>
/// 是否在线
/// </summary>
public bool IsCon { set; get; }
/// <summary>
/// 是否可用
/// </summary>
private bool _IsUse = true;
public bool IsUse
{
set
{
if (!value.Equals(_IsUse))
{
_IsUse = value;
Common.WriteIni(Name, SettingString.IsUse, _IsUse.ToString());
}
}
get { return _IsUse; }
}
/// <summary>
/// 地点
/// </summary>
public string Place { set; get; }
/// <summary>
/// 地点
/// </summary>
public string PlaceAliceName { set; get; } = "";
/// <summary>
/// 地点的状态
/// </summary>
public ePlaceState PlaceState { private set; get; }
/// <summary>
/// 小车的状态ID,(从小车获取)
/// </summary>
public eAGVState StateID { private set; get; }
/// <summary>
/// 负载
/// </summary>
public bool IsExistShelf { set; get; } = false;
/// <summary>
/// 电量百分比,(从小车获取)
/// </summary>
public int Battery { private set; get; }
/// <summary>
/// 当前任务文本,(从小车获取)
/// </summary>
public string MissionText { set; get; }
public class clsPosition
{
public double orientation { get; set; }
public double x { get; set; }
public double y { get; set; }
}
/// <summary>
/// 当前位置
/// </summary>
public clsPosition Position;
/// <summary>
/// 任务内容
/// </summary>
public string Msg
{
get;
set;
} = "";
/// <summary>
/// 当前任务
/// </summary>
public Job CurJob { get; set; }
/// <summary>
/// 当前任务的ID号
/// </summary>
public int CurTaskID { get; set; } = -1;
public string CurTaskState { get; set; } = "";
/// <summary>
/// 当前任务名称
/// </summary>
public string CurTaskName { get; set; }
/// <summary>
/// 当前任务的GUID
/// </summary>
public string CurTaskGUID { get; set; }
/// <summary>
/// 当前料架的工单信息
/// </summary>
public string BoxDestInfo { get; set; } = "";
public string RunInfo()
{
string curJobTaskName = "";
string curJobTaskState = "";
int curJobTaskID = -1;
if (CurJob != null)
{
if (CurJob is ChargeJob)
{
curJobTaskName = ((ChargeJob)CurJob).CurTaskName;
curJobTaskState = ((ChargeJob)CurJob).CurTaskState;
curJobTaskID = ((ChargeJob)CurJob).CurTaskID;
}
else if (CurJob is EmptyAGVBackJob)
{
curJobTaskName = ((EmptyAGVBackJob)CurJob).CurTaskName;
curJobTaskState = ((EmptyAGVBackJob)CurJob).CurTaskState;
curJobTaskID = ((EmptyAGVBackJob)CurJob).CurTaskID;
}
else if (CurJob is EmptyShelfBackJob)
{
curJobTaskName = ((EmptyShelfBackJob)CurJob).CurTaskName;
curJobTaskState = ((EmptyShelfBackJob)CurJob).CurTaskState;
curJobTaskID = ((EmptyShelfBackJob)CurJob).CurTaskID;
}
else if (CurJob is EnterLeaveShelfJob)
{
curJobTaskName = ((EnterLeaveShelfJob)CurJob).CurTaskName;
curJobTaskState = ((EnterLeaveShelfJob)CurJob).CurTaskState;
curJobTaskID = ((EnterLeaveShelfJob)CurJob).CurTaskID;
}
else if (CurJob is GoEmptyShelfLineJob)
{
curJobTaskName = ((GoEmptyShelfLineJob)CurJob).CurTaskName;
curJobTaskState = ((GoEmptyShelfLineJob)CurJob).CurTaskState;
curJobTaskID = ((GoEmptyShelfLineJob)CurJob).CurTaskID;
}
else if (CurJob is GoFullShelfStationJob)
{
curJobTaskName = ((GoFullShelfStationJob)CurJob).CurTaskName;
curJobTaskState = ((GoFullShelfStationJob)CurJob).CurTaskState;
curJobTaskID = ((GoFullShelfStationJob)CurJob).CurTaskID;
}
else if (CurJob is SendFullShelfToLineJob)
{
curJobTaskName = ((SendFullShelfToLineJob)CurJob).CurTaskName;
curJobTaskState = ((SendFullShelfToLineJob)CurJob).CurTaskState;
curJobTaskID = ((SendFullShelfToLineJob)CurJob).CurTaskID;
}
if (RFID.StartsWith("C"))
{
return string.Format("设备:{1}{0}RFID:{2}{0}任务信息:[任务名称={3}][任务状态:{4}]{0}当前步骤:{5}{0}执行信息:{6}",
"\r\n", Name, RFID, curJobTaskName, curJobTaskState, Msg, MissionText);
}
else if (RFID.StartsWith("D"))
{
return string.Format("设备:{1}{0}RFID:{2}{0}任务信息:[任务名称={3}][任务状态={4}]{0}当前步骤:{5}{0}执行信息:{6}",
"\r\n", Name, RFID, curJobTaskName, curJobTaskState, Msg, MissionText);
}
else
return string.Format("设备:{1}{0}RFID:{2}{0}任务信息:[任务名称={3}][任务状态={4}]{0}当前步骤:{5}{0}执行信息:{6}",
"\r\n", Name, RFID, curJobTaskName, curJobTaskState, Msg, MissionText);
//if (RFID.StartsWith("C"))
//{
// return string.Format("Name:{1}{0}RFID:{2}{0}CurJob:{3}{0}CurJobTaskInfo:[TaskName={4}][TaskID={5}][TaskState={6}]{0}RunInfo:{7}{0}BoxDestInfo:{8}{0}GetRack:{9}{0}MissionText:{10}",
// "\r\n", Name, RFID, CurJob.ToString(), curJobTaskName, curJobTaskID, curJobTaskState, Msg, BoxDestInfo, BLL.AGVManager.GetRackBy(RFID), MissionText);
//}
//else if (RFID.StartsWith("D"))
//{
// return string.Format("Name:{1}{0}RFID:{2}{0}CurJob:{3}{0}CurJobTaskInfo:[TaskName={4}][TaskID={5}][TaskState={6}]{0}RunInfo:{7}{0}BoxDestInfo:{8}{0}MissionText:{9}",
// "\r\n", Name, RFID, CurJob.ToString(), curJobTaskName, curJobTaskID, curJobTaskState, Msg, BoxDestInfo, MissionText);
//}
//else
// return string.Format("Name:{1}{0}RFID:{2}{0}CurJob:{3}{0}CurJobTaskInfo:[TaskName={4}][TaskID={5}][TaskState={6}]{0}RunInfo:{7}{0}MissionText:{8}",
// "\r\n", Name, RFID, CurJob.ToString(), curJobTaskName, curJobTaskID, curJobTaskState, Msg, MissionText);
}
else
return string.Format("设备:{1}{0}RFID:{2}{0}任务信息:[任务名称={3}][任务状态={4}]{0}执行信息:{5}",
"\r\n", Name, RFID, curJobTaskName, curJobTaskState, MissionText);
//return string.Format("Name:{1}{0}RFID:{2}{0}CurTaskInfo:[TaskName={3}][TaskID={4}][TaskState={5}]{0}MissionText:{6}",
// "\r\n", Name, RFID, curJobTaskName, curJobTaskID, curJobTaskState, MissionText);
}
/// <summary>
/// 任务重发
/// </summary>
public void Resend()
{
if (CurJob != null)
{
if (CurJob is ChargeJob)
{
((ChargeJob)CurJob).ResendTask(this);
}
else if (CurJob is EmptyAGVBackJob)
{
((EmptyAGVBackJob)CurJob).ResendTask(this);
}
else if (CurJob is EmptyShelfBackJob)
{
((EmptyShelfBackJob)CurJob).ResendTask(this);
}
else if (CurJob is EnterLeaveShelfJob)
{
((EnterLeaveShelfJob)CurJob).ResendTask(this);
}
else if (CurJob is GoEmptyShelfLineJob)
{
((GoEmptyShelfLineJob)CurJob).ResendTask(this);
}
else if (CurJob is GoFullShelfStationJob)
{
((GoFullShelfStationJob)CurJob).ResendTask(this);
}
else if (CurJob is SendFullShelfToLineJob)
{
((SendFullShelfToLineJob)CurJob).ResendTask(this);
}
}
}
/// <summary>
/// 停在同一处超时
/// </summary>
public bool StandTimeOut { get; set; } = false;
public Agv_Info(string id, string name, string ip, string authorization, string ioID, bool isUse, string rfid)
{
ID = id;
Name = name;
IP = ip;
Authorization = authorization;
IOID = ioID;
RFID = rfid;
IsCon = false;
_IsUse = isUse;
Place = "";
Msg = "";
Position = new Agv_Info.clsPosition();
}
DateTime IoStartTime = DateTime.MaxValue;
int IoLastTime = 5000;
int StandLastTimeMinute = 5;
public DateTime StandStartTime = DateTime.MaxValue;
public bool SetState(eAGVState stateID, string stateText, int battery, string missionText, clsPosition position)
{
bool isChange = false;
bool preShelfState = IsExistShelf;
Common.mir.Get_IO_Status(this, out bool[] input, out bool[] output);
if (input != null && input.Length == 4)
{
bool reachIoValue = input[3].Equals(true);//input[2] &&
if (reachIoValue)
{
//满足给定的IO值,计算持续时间
if (IoStartTime == DateTime.MaxValue)
{
IoStartTime = DateTime.Now;
}
if (IoLastTime > 0)
{
//持续时间
TimeSpan lastTimeSpan = DateTime.Now - IoStartTime;
IsExistShelf = (lastTimeSpan.TotalMilliseconds >= IoLastTime);
}
else
{
IsExistShelf = true;
}
}
else
{
//重新计时
IoStartTime = DateTime.MinValue;
IsExistShelf = input[3];
}
}
if (!StateID.Equals(stateID) || !CurTaskState.Equals(stateText) || !Battery.Equals(battery)
|| !MissionText.Equals(missionText) || !IsExistShelf.Equals(preShelfState))
isChange = true;
StateID = stateID;
CurTaskState = stateText;
Battery = battery;
MissionText = missionText;
CheckStandTimeOut(position);
return isChange;
}
/// <summary>
/// 检查小车是否在原地停留超时
/// </summary>
/// <returns></returns>
private void CheckStandTimeOut(clsPosition position)
{
if (IsUse && CurJob !=null && !(CurJob is ChargeJob) &&
( !CurTaskName.Contains(SettingString.Standby)))//!CurTaskName.Contains(SettingString.AutoCharge) ||
{
if (Math.Abs(position.x - Position.x) < 1 && Math.Abs(position.y - Position.y) < 1)
{
//满足条件,计算持续时间
if (StandStartTime == DateTime.MaxValue)
{
StandStartTime = DateTime.Now;
}
TimeSpan lastTimeSpan = DateTime.Now - StandStartTime;
StandTimeOut = (lastTimeSpan.TotalMinutes >= StandLastTimeMinute);
}
else
{
//重新计时
StandStartTime = DateTime.Now;
StandTimeOut = false;
}
}
else if(CurJob != null && (CurJob is ChargeJob))
{
StandTimeOut = false;
StandStartTime = DateTime.Now;
}
else
{
StandTimeOut = false;
StandStartTime = DateTime.Now;
}
Position = position;
}
//public void GetPlace(int value)
//{
// // Common.log.Debug(Name + " PLC20=" + value);
// if (value == 0)
// {
// Place = "";
// PlaceState = ePlaceState.None;
// }
// else if (value > 0 && value < 1000)
// {
// //Place = "";
// //PlaceState = PlaceState.None;
// //TaskSend = "";
// }
// else if (value >= 1000)
// {
// int a = value / 1000;
// int b = (value - a * 1000) / 10;
// int c = value - a * 1000 - b * 10;
// //if (c.Equals(1) || c.Equals(3) || c.Equals(5))//Move,Enter,Leave
// // TaskSend = "";
// Place = (char)(64 + a) + b.ToString();
// if (Common.nodeInfo != null && Common.nodeInfo.Count != 0)
// {
// ClientNode node = Common.nodeInfo.Find(s => s.Name == Place);
// if (node != null)
// PlaceAliceName = node.AliceName;
// else
// PlaceAliceName = Place;
// }
// PlaceState = (ePlaceState)c;
// }
//}
public string[] ToRow()
{
//AGV名称,IP,AGV状态,任务状态,地点,后续任务,在线,电量,调用,清除缓存
List<string> s = new List<string>();
s.Add(Name);
s.Add(IP);
s.Add(StateID.ToString());
s.Add(CurTaskID.ToString());
s.Add(CurTaskName);
s.Add(CurTaskState);
//s.Add(Msg);
// s.Add(MissionText);
if (Common.nodeInfo != null && Common.nodeInfo.Count != 0)
{
ClientNode node = Common.nodeInfo.Find(ss => ss.Name == Place);
if (node != null)
PlaceAliceName = node.AliceName;
else
PlaceAliceName = Place;
}
s.Add(PlaceAliceName);
s.Add(IsExistShelf ? "满载" : "空载");
s.Add(IsCon ? "在线" : "离线");
s.Add(Battery + "%");
s.Add(IsUse ? "是" : "否");
return s.ToArray();
}
}
/// <summary>
/// MIR 状态,与状态ID对应
/// </summary>
public enum eAGVState
{
None = 0,
Starting,
ShuttingDown,
Ready,
Pause,
Executing,
Aborted,
Completed,
Docked,
Docking,
EmergencyStop,
ManualControl,
Error,
UNKNOWN
}
}
using AGVControl;
using System;
using System.Collections.Generic;
namespace AGVControl
{
public abstract class Job
{
/// <summary>
/// 是否任务正在执行,防止任务执行时间过长产生多线程问题
/// </summary>
public bool IsProcess { get; set; }
/// <summary>
/// 运行信息
/// </summary>
public abstract string RunInfo { get; }
/// <summary>
/// 根据任务状态继续执行任务
/// </summary>
public abstract Job Execute(Agv_Info agv);
public int CurTaskID { get; set; } = -1;
/// <summary>
/// 当前的任务名称(与任务GUID对应)
/// </summary>
public string CurTaskName { get; set; } = "";
/// <summary>
/// 当前任务的执行状态
/// </summary>
public string CurTaskState { get; set; } = "Wait";
/// <summary>
/// 更新任务信息
/// </summary>
/// <param name="curTaskName"></param>
/// <param name="curTaskId"></param>
protected void UpdateJobTaskInfo(string curTaskName, int curTaskId)
{
CurTaskID = curTaskId;
CurTaskName = curTaskName;
//CurTaskState = SettingString.Wait;
CurTaskState = Common.GetTakJobState(CurTaskID);
}
/// <summary>
/// 任务重发
/// </summary>
/// <returns></returns>
public bool ResendTask(Agv_Info agv)
{
bool rtn = false;
if (!CurTaskID.Equals(-1) && Common.mir.Get_Task_State(CurTaskID, out string stateStr))
{
if (stateStr.Equals(SettingString.Aborted))
{
rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission[CurTaskName]);
if (rtn)
{
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
return true;
}
}
}
else if (!CurTaskName.Equals("") && !Common.agvMission[CurTaskName].Equals(agv.CurTaskGUID))//Job的当前任务与agv最新任务不一致
{
rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission[CurTaskName]);
if (rtn)
{
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
return true;
}
}
else if (CurTaskID.Equals(-1))//任务发送失败,重新发送
{
rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission[CurTaskName]);
if (rtn)
{
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
return true;
}
}
return false;
}
}
}
using AGVControl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AGVControl
{
public class JobStep<T> where T : Enum
{
private T step;
private string msg = "";
public string Msg
{
get { return msg; }
set
{
if (!string.IsNullOrEmpty(value))
{
value = step.ToString() + ":" + value;
//不为空,且与上一个消息不一样才打印
if (!value.Equals(msg))
{
Common.LogInfo(value);
}
}
msg = value;
}
}
private DateTime startTime = DateTime.Now;
public JobStep(T initStep)
{
this.step = initStep;
this.msg = "";
}
/// <summary>
/// 当前步骤是否是某个步骤
/// </summary>
/// <param name="step"></param>
/// <returns></returns>
public bool IsStep(T step)
{
return this.step.Equals(step);
}
/// <summary>
/// 是否超时
/// </summary>
/// <param name="timeOutMilliseconds"></param>
/// <returns></returns>
public bool IsTimeOut(int timeOutMilliseconds,out double timeOutValue)
{
timeOutValue = 0;
TimeSpan span = DateTime.Now - startTime;
if (span.TotalMilliseconds > timeOutMilliseconds)
{
timeOutValue = span.TotalSeconds;
return true;
}
return false;
}
/// <summary>
/// 进入下一个步骤
/// </summary>
/// <param name="nextStep"></param>
public void ToNextStep(T nextStep)
{
step = nextStep;
startTime = DateTime.Now;
}
public string CurStep()
{
return step.ToString();
}
}
}
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace AGVControl
{
public abstract class Node
{
/// <summary>
/// 节点名称
/// </summary>
public string Name { get;}
/// <summary>
/// 节点IP
/// </summary>
public string IP { get; }
/// <summary>
/// 在线状态
/// </summary>
public bool Online { get; set; }
/// <summary>
/// 是否可调用
/// </summary>
public bool IsUse { set; get; }
/// <summary>
/// 节点状态
/// </summary>
protected eNodeStatus nodeStatus;
public Node(string name,string ip,bool isUse=false)
{
Name = name;
IP = ip;
Online = false;
IsUse = isUse;
nodeStatus = eNodeStatus.None;
}
public Node(string name)
{
Name = name;
}
public bool StateEquals(eNodeStatus obj)
{
return nodeStatus.Equals(obj);
}
/// <summary>
/// 获取当前状态
/// </summary>
/// <returns></returns>
public eNodeStatus GetState()
{
return nodeStatus;
}
/// <summary>
/// 更新节点状态
/// </summary>
/// <param name="status"></param>
public void UpdateNodeStatus(eNodeStatus status)
{
nodeStatus = status;
}
public virtual Job GetNewJob(Agv_Info currentAgvBean)
{
return null;
}
}
/// <summary>
/// 节点状态
/// </summary>
public enum eNodeStatus : byte
{
/// <summary>
/// 没有动作
/// </summary>
None = 0,
/// <summary>
/// 需要7寸D料架
/// </summary>
NeedD = 1,
/// <summary>
/// 需要大尺寸C料架
/// </summary>
NeedC = 2,
/// <summary>
/// 需要进入料架
/// </summary>
NeedEnter = 3,
/// <summary>
/// 需要出去料架
/// </summary>
NeedLeave = 4,
/// <summary>
/// 需要进入离开料架
/// </summary>
NeedEnterLeave = 5,
/// <summary>
/// 准备进入料架,服务器发送
/// </summary>
ReadyEnter = 6,
/// <summary>
/// 可以进入料架
/// </summary>
MayEnter = 7,
/// <summary>
/// 完成进入料架
/// </summary>
FinishEnter = 8,
/// <summary>
/// 准备离开料架,服务器发送
/// </summary>
ReadyLeave = 9,
/// <summary>
/// 可以出去料架
/// </summary>
MayLeave = 10,
/// <summary>
/// 完成出去料架
/// </summary>
FinishLeave = 11,
}
/// <summary>
/// 客户端的优先级
/// </summary>
public enum ClientLevel : byte
{
/// <summary>
/// 低
/// </summary>
Low = 0,
/// <summary>
/// 中等
/// </summary>
Middle = 1,
/// <summary>
/// 高
/// </summary>
High = 2
}
}
文件属性发生变化

using AGVControl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.PeerResolvers;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AGVControl
{
/// <summary>
/// 充电任务
/// </summary>
public class ChargeJob : Job
{
/// <summary>
/// 出完满料后-空车返回任务
/// </summary>
/// <param name="agvPlae">小车当前位置,空表示在待机位</param>
public ChargeJob(string agvPlae)
{
this.agvPlace = agvPlae;
}
/// <summary>
/// 接收任务时,agv的位置
/// </summary>
private string agvPlace = "";
private string runInfo = "";
/// <summary>
/// 运行信息
/// </summary>
public override string RunInfo
{
get { return runInfo; }
}
private JobStep<CHARGE_STEP> ChargeStep = new JobStep<CHARGE_STEP>(CHARGE_STEP.NONE);
/// <summary>
/// 空车返回执行
/// </summary>
/// <param name="agv"></param>
public override Job Execute(Agv_Info agv)
{
string msg = agv.Name + " ";
bool rtn = false;
runInfo = "";
agv.Msg = runInfo;
//if (!CurTaskID.Equals(-1) && Common.mir.Get_Task_State(CurTaskID, out string st))
// CurTaskState = st;
CurTaskState = Common.GetTakJobState(CurTaskID);
if (ChargeStep.IsStep(CHARGE_STEP.NONE))
{
if (agv.Battery > Common.chargeStatus.chargeMax)
{
if (agv.Place.Equals(SettingString.Standby))//在待机位不操作
{
ChargeStep.ToNextStep(CHARGE_STEP.END);
runInfo = "在待机位,电量充足[" + agv.Battery + "%],等待任务";
msg += runInfo;
ChargeStep.Msg = msg;
}
else if (agvPlace.StartsWith(SettingString.C4_Name_Prefix))
{
ChargeStep.ToNextStep(CHARGE_STEP.WAIT_AGV_REACH_4D_DOOR);
runInfo = "电量充足[" + agv.Battery + "%],从当前位置" + agvPlace + "回到待机位,先到4D门";
msg += runInfo;
ChargeStep.Msg = msg;
Common.DoorMission(agv, SettingString.DoorCToD);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else
{
ChargeStep.ToNextStep(CHARGE_STEP.WAIT_REACH_STANDBY);
runInfo = "电量充足[" + agv.Battery + "%],从当前位置" + agvPlace + "回到待机位";
msg += runInfo;
ChargeStep.Msg = msg;
//Common.StatusCharge(agv);
Common.MoveToNode(agv, SettingString.Standby);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
else
{
if (agvPlace.StartsWith(SettingString.C4_Name_Prefix))
{
ChargeStep.ToNextStep(CHARGE_STEP.WAIT_AGV_REACH_4D_DOOR);
runInfo = "电量[" + agv.Battery + "%]小于最大电量[" + Common.chargeStatus.chargeMax + "%],从当前位置" + agvPlace + "回到充电位,先到4D门";
msg += runInfo;
ChargeStep.Msg = msg;
Common.DoorMission(agv, SettingString.DoorCToD);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else
{
if (!Common.StatusCharge(agv))
{
ChargeStep.ToNextStep(CHARGE_STEP.WAIT_REACH_STANDBY);
runInfo = "电量[" + agv.Battery + "%]小于最大电量[" + Common.chargeStatus.chargeMax + "%],充电桩有小车,从当前位置" + agvPlace + "回到待机位";
msg += runInfo;
ChargeStep.Msg = msg;
Common.MoveToNode(agv, SettingString.Standby);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else
{
ChargeStep.ToNextStep(CHARGE_STEP.WAIT_REACH_CHARGE_STATION);
runInfo = "电量[" + agv.Battery + "%]小于最大电量[" + Common.chargeStatus.chargeMax + "%],从当前位置" + agvPlace + "回到充电位";
msg += runInfo;
ChargeStep.Msg = msg;
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
}
}
else if (ChargeStep.IsStep(CHARGE_STEP.WAIT_AGV_REACH_4D_DOOR))
{
if (Common.CheckTaskFinished(agv, SettingString.DoorCToD, CurTaskState))
{
if (agv.Battery > Common.chargeStatus.chargeMax)
{
ChargeStep.ToNextStep(CHARGE_STEP.WAIT_REACH_STANDBY);
runInfo = "电量充足[" + agv.Battery + "%],从当前位置" + agvPlace + "回到待机位";
msg += runInfo;
ChargeStep.Msg = msg;
Common.MoveToNode(agv, SettingString.Standby);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else
{
if (!Common.StatusCharge(agv))
{
ChargeStep.ToNextStep(CHARGE_STEP.WAIT_REACH_STANDBY);
runInfo = "电量[" + agv.Battery + "%]小于最大电量[" + Common.chargeStatus.chargeMax + "%],充电桩有小车,从当前位置" + agvPlace + "回到待机位";
msg += runInfo;
ChargeStep.Msg = msg;
Common.MoveToNode(agv, SettingString.Standby);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else
{
ChargeStep.ToNextStep(CHARGE_STEP.WAIT_REACH_CHARGE_STATION);
runInfo = "电量[" + agv.Battery + "%]小于最大电量[" + Common.chargeStatus.chargeMax + "%],从当前位置" + agvPlace + "回到充电位";
msg += runInfo;
ChargeStep.Msg = msg;
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
}
}
else if (ChargeStep.IsStep(CHARGE_STEP.WAIT_REACH_CHARGE_STATION))
{
if (Common.CheckTaskFinished(agv, CurTaskName))
{
ChargeStep.ToNextStep(CHARGE_STEP.WAIT_REACH_CHARGE_OK);
runInfo = "充电任务分配完成,去充电且等待任务";
msg += runInfo;
ChargeStep.Msg = msg;
}
}
else if (ChargeStep.IsStep(CHARGE_STEP.WAIT_REACH_CHARGE_OK))
{
if (CheckRandomCharge(agv))
{
if (agv.Battery >= Common.chargeStatus.chargeMax)
{
ChargeStep.ToNextStep(CHARGE_STEP.WAIT_REACH_STANDBY);
runInfo = "电量充足,回待机位";
msg += runInfo;
ChargeStep.Msg = msg;
Common.chargeStatus.ClearRandomChargeInfo(agv);
Common.MoveToNode(agv, SettingString.Standby);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else if (agv.Battery >= Common.chargeStatus.chargeMin)
{
Job job = Common.control.GetJob(agv);
if (job != null && !(job is ChargeJob))
{
Common.chargeStatus.ClearRandomChargeInfo(agv);
runInfo = "充电过程检测到任务,电量[" + agv.Battery + "%]大于最小电量[" + Common.chargeStatus.chargeMin + "%],中断充电执行任务";
msg += runInfo;
ChargeStep.Msg = msg;
return job;
}
}
}
else//固定充电桩
{
if (agv.Battery >= Common.chargeStatus.chargeMax)
{
ChargeStep.ToNextStep(CHARGE_STEP.END);
runInfo = "充电完成";
msg += runInfo;
ChargeStep.Msg = msg;
}
else if (agv.Battery >= Common.chargeStatus.chargeMin)
{
Job job = Common.control.GetJob(agv);
if (job != null && !(job is ChargeJob))
{
runInfo = "充电过程检测到任务,电量[" + agv.Battery + "%]大于最小电量[" + Common.chargeStatus.chargeMin + "%],中断充电执行任务";
msg += runInfo;
ChargeStep.Msg = msg;
Common.chargeStatus.ClearRandomChargeInfo(agv);
return job;
}
//else if (job == null && agv.Battery < Common.chargeStatus.chargeMax / 2)
//{
// ChargeStep.ToNextStep(CHARGE_STEP.NONE);
// runInfo = "在待机位暂无任务,且当前电量小于" + Common.chargeStatus.chargeMax / 2 + "%,去充电位";
// msg += runInfo;
// ChargeStep.Msg = msg;
// Common.chargeStatus.ClearRandomChargeInfo(agv);
//}
}
}
}
else if (ChargeStep.IsStep(CHARGE_STEP.WAIT_REACH_STANDBY))
{
if (Common.CheckTaskFinished(agv, SettingString.Standby, CurTaskState))
{
ChargeStep.ToNextStep(CHARGE_STEP.END);
runInfo = "充电完成,到达待机位";
msg += runInfo;
ChargeStep.Msg = msg;
}
}
else if (ChargeStep.IsStep(CHARGE_STEP.END))
{
runInfo = "等待任务";
Job job = Common.control.GetJob(agv);
if (job != null && !(job is ChargeJob))
{
runInfo = "在待机位检测到任务,执行任务";
msg += runInfo;
ChargeStep.Msg = msg;
Common.chargeStatus.ClearRandomChargeInfo(agv);
return job;
}
else if (job == null && agv.Battery < Common.chargeStatus.chargeMax / 2)
{
ChargeStep.ToNextStep(CHARGE_STEP.NONE);
runInfo = "在待机位暂无任务,且当前电量小于" + Common.chargeStatus.chargeMax / 2 + "%,去充电位";
msg += runInfo;
ChargeStep.Msg = msg;
Common.chargeStatus.ClearRandomChargeInfo(agv);
}
}
return this;
}
/// <summary>
/// 检查当前小车是否是共用充电桩的小车
/// </summary>
/// <returns></returns>
private bool CheckRandomCharge(Agv_Info agv)
{
if (agv.IP.Equals(SettingString.RandomCharge_IP1) || agv.IP.Equals(SettingString.RandomCharge_IP2) ||
agv.IP.Equals(SettingString.RandomCharge_IP3) || agv.IP.Equals(SettingString.RandomCharge_IP4))
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// AGV充电流程
/// </summary>
private enum CHARGE_STEP
{
/// <summary>
///
/// </summary>
NONE,
/// <summary>
/// 等待到达4D门
/// </summary>
WAIT_AGV_REACH_4D_DOOR,
/// <summary>
/// 等待AGV到达充电位
/// </summary>
WAIT_REACH_CHARGE_STATION,
/// <summary>
/// 等待充电完成
/// </summary>
WAIT_REACH_CHARGE_OK,
/// <summary>
/// 充电完成去待机位
/// </summary>
WAIT_REACH_STANDBY,
/// <summary>
///
/// </summary>
END
}
}
}

using AGVControl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.PeerResolvers;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AGVControl
{
/// <summary>
/// 空车返回待机位任务
/// </summary>
public class EmptyAGVBackJob : Job
{
/// <summary>
/// 出完满料后-空车返回任务
/// </summary>
/// <param name="agvPlae">小车当前位置,空表示在待机位</param>
/// <param name="palce">空料架位置点</param>
public EmptyAGVBackJob(string agvPlae)
{
this.agvPlace = agvPlae;
}
/// <summary>
/// 接收任务时,agv的位置
/// </summary>
private string agvPlace { get; set; }
private string runInfo = "";
/// <summary>
/// 运行信息
/// </summary>
public override string RunInfo
{
get { return runInfo; }
}
private JobStep<EMPTY_AGV_BACK_STEP> EmptyAGVBackStep = new JobStep<EMPTY_AGV_BACK_STEP>(EMPTY_AGV_BACK_STEP.NONE);
/// <summary>
/// 空车返回执行
/// </summary>
/// <param name="agv"></param>
public override Job Execute(Agv_Info agv)
{
string msg = agv.Name + " ";
bool rtn = false;
agv.Msg = runInfo;
//if (!CurTaskID.Equals(-1) && Common.mir.Get_Task_State(CurTaskID, out string st))
// CurTaskState = st;
CurTaskState = Common.GetTakJobState(CurTaskID);
if (EmptyAGVBackStep.IsStep(EMPTY_AGV_BACK_STEP.NONE))
{
if (Common.FindEmptyShelfNode(agv, out string nodeName, true))
{
int i = Common.agvInfo.FindIndex(s => s.CurJob is GoEmptyShelfLineJob && ((GoEmptyShelfLineJob)s.CurJob).EmptyShelfPlace.Equals(nodeName));
if(i==-1)
{
runInfo= "小车在产线 " + agvPlace + " 准备返回时检测到 " + nodeName + " 有空料架";
msg += runInfo;
EmptyAGVBackStep.Msg = msg;
return new GoEmptyShelfLineJob(agvPlace, nodeName);
}
else
{
if (agvPlace.StartsWith(SettingString.C4_Name_Prefix))
{
EmptyAGVBackStep.ToNextStep(EMPTY_AGV_BACK_STEP.WAIT_AGV_REACH_4D_DOOR);
runInfo= "从产线" + agvPlace + "回待机位,先到4D门";
msg += runInfo;
EmptyAGVBackStep.Msg = msg;
Common.DoorMission(agv, SettingString.DoorCToD);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else
{
EmptyAGVBackStep.ToNextStep(EMPTY_AGV_BACK_STEP.WAIT_REACH_STANDBY);
runInfo= "从产线" + agvPlace + "回待机位";
msg += runInfo;
EmptyAGVBackStep.Msg = msg;
Common.MoveToNode(agv, SettingString.Standby);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
//EmptyAGVBackStep.ToNextStep(EMPTY_AGV_BACK_STEP.END);
}
else
{
if (agvPlace.StartsWith(SettingString.C4_Name_Prefix))
{
EmptyAGVBackStep.ToNextStep(EMPTY_AGV_BACK_STEP.WAIT_AGV_REACH_4D_DOOR);
runInfo= "从产线" + agvPlace + "回待机位,先到4D门";
msg += runInfo;
EmptyAGVBackStep.Msg = msg;
Common.DoorMission(agv, SettingString.DoorCToD);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else
{
EmptyAGVBackStep.ToNextStep(EMPTY_AGV_BACK_STEP.WAIT_REACH_STANDBY);
runInfo= "从产线" + agvPlace + "回待机位";
msg += runInfo;
EmptyAGVBackStep.Msg = msg;
Common.MoveToNode(agv, SettingString.Standby);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
}
else if (EmptyAGVBackStep.IsStep(EMPTY_AGV_BACK_STEP.WAIT_REACH_STANDBY))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckTaskFinished(agv, SettingString.Standby,CurTaskState))
{
Job job = Common.control.GetJob(agv);
if (job == null && agv.Battery < Common.chargeStatus.chargeMax)
{
runInfo= "到达待机位,电量[" + agv.Battery + "]小于最大电量[" + Common.chargeStatus.chargeMax + "],暂无任务,去充电";
msg += runInfo;
EmptyAGVBackStep.Msg = msg;
return new ChargeJob("");
}
else
{
runInfo= "到达待机位,检测到新任务,执行任务";
msg += runInfo;
EmptyAGVBackStep.Msg = msg;
return job;
}
}
else
{
if (Common.FindFullShelfTask(agv))
{
runInfo= "从产线" + agvPlace + "回待机位过程中,检测到A6出满料,去A6";
msg += runInfo;
EmptyAGVBackStep.Msg = msg;
return new GoFullShelfStationJob(SettingString.Standby);
}
//else
//{
// msg = "从产线" + agvPlace + "到达4D门,暂无任务,去充电位";
// EmptyAGVBackStep.Msg = msg;
// return new ChargeJob(SettingString.D4_DOOR_Name);
//}
}
}
//else if (EmptyAGVBackStep.IsStep(EMPTY_AGV_BACK_STEP.WAIT_AGV_REACH_4D_DOOR))
//{
// CurTaskState = Common.GetTakJobState(CurTaskID);
// if (Common.CheckTaskFinished(agv, SettingString.DoorCToD, CurTaskState))
// {
// EmptyAGVBackStep.ToNextStep(EMPTY_AGV_BACK_STEP.WAIT_REACH_STANDBY);
// runInfo = "从产线" + agvPlace + "回待机位";
// msg += runInfo;
// EmptyAGVBackStep.Msg = msg;
// }
//}
else if (EmptyAGVBackStep.IsStep(EMPTY_AGV_BACK_STEP.WAIT_AGV_REACH_4D_DOOR))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckTaskFinished(agv, SettingString.DoorCToD, CurTaskState))
{
if (Common.FindFullShelfTask(agv))
{
runInfo = "从产线" + agvPlace + "到达4D门,检测到A6出满料,去A6";
msg += runInfo;
EmptyAGVBackStep.Msg = msg;
return new GoFullShelfStationJob(SettingString.DoorCToD);
}
else
{
runInfo = "从产线" + agvPlace + "到达4D门,暂无任务,去充电位";
msg += runInfo;
EmptyAGVBackStep.Msg = msg;
return new ChargeJob(SettingString.DoorCToD);
}
}
}
return this;
}
/// <summary>
/// AGV回收空料架流程
/// </summary>
private enum EMPTY_AGV_BACK_STEP
{
/// <summary>
/// 查询任务
/// </summary>
NONE,
/// <summary>
/// 等待到达4D门
/// </summary>
WAIT_AGV_REACH_4D_DOOR,
/// <summary>
/// 等待恒邑反馈
/// </summary>
WAIT_HY_RESPONSE,
/// <summary>
/// 等待AGV到达待机位
/// </summary>
WAIT_REACH_STANDBY,
/// <summary>
///
/// </summary>
END
}
}
}

using AGVControl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.ModelBinding;
using System.Windows.Forms;
namespace AGVControl
{
public enum eShelfType
{
BigShelf,
SmallShelf
}
/// <summary>
/// 载空料架返回任务,A5,A6需要则直接去,否则在待机位等待
/// </summary>
public class EmptyShelfBackJob : Job
{
/// <summary>
/// 载空料架返回任务
/// </summary>
/// <param name="lineName">产线的节点名称</param>
public EmptyShelfBackJob(string lineName, eShelfType shelfType)
{
EmptyShelfPlace = lineName;
this.shelfType = shelfType;
}
/// <summary>
/// 空料架的产线位置
/// </summary>
private string EmptyShelfPlace { get; set; }
/// <summary>
/// 空料架目的地
/// </summary>
public string EmptyShelfTargetPlace { get; set; } = "";
private int tryTimes = 0;
private eShelfType shelfType;
private string runInfo = "";
/// <summary>
/// 运行信息
/// </summary>
public override string RunInfo
{
get { return runInfo; }
}
private JobStep<EMPTY_SHELF_BACK_STEP> EmptyBackStep = new JobStep<EMPTY_SHELF_BACK_STEP>(EMPTY_SHELF_BACK_STEP.NONE);
/// <summary>
/// 空架任务执行
/// </summary>
/// <param name="agv"></param>
public override Job Execute(Agv_Info agv)
{
string msg = agv.Name+ " ";
bool rtn = false;
agv.Msg = runInfo;
//if (!CurTaskID.Equals(-1) && Common.mir.Get_Task_State(CurTaskID, out string st))
// CurTaskState = st;
if (EmptyBackStep.IsStep(EMPTY_SHELF_BACK_STEP.NONE))
{
if (EmptyShelfPlace.StartsWith(SettingString.C4_Name_Prefix))//4C车间
{
EmptyBackStep.ToNextStep(EMPTY_SHELF_BACK_STEP.WAIT_AGV_REACH_DOOR);
runInfo= "空料架从产线" + EmptyShelfPlace + "前往4D门";
msg += runInfo;
EmptyBackStep.Msg = msg;
Common.DoorMission(agv, SettingString.DoorCToD);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else
{
if (Common.CheckA5A6State(agv, shelfType, out string nodeName))
{
EmptyShelfTargetPlace = nodeName;
EmptyBackStep.ToNextStep(EMPTY_SHELF_BACK_STEP.WAIT_AGV_REACH_A5A6);
runInfo= "空料架从产线 [" + EmptyShelfPlace + "] 送往双层线" + EmptyShelfTargetPlace;
msg += runInfo;
EmptyBackStep.Msg = msg;
if (!EmptyShelfTargetPlace.Equals(""))
{
Common.MoveToNode(agv, EmptyShelfTargetPlace);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
else
{
EmptyBackStep.ToNextStep(EMPTY_SHELF_BACK_STEP.WAIT_AGV_REACH_STANDBY);
runInfo= "双层线暂不需要空料架,从产线[" + EmptyShelfPlace + "]到待机位";
msg += runInfo;
EmptyBackStep.Msg = msg;
Common.MoveToNode(agv, SettingString.Standby);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
}
else if (EmptyBackStep.IsStep(EMPTY_SHELF_BACK_STEP.WAIT_AGV_REACH_DOOR))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckTaskFinished(agv, SettingString.DoorCToD, CurTaskState))
{
if (Common.CheckA5A6State(agv, shelfType, out string nodeName))
{
EmptyShelfTargetPlace = nodeName;
EmptyBackStep.ToNextStep(EMPTY_SHELF_BACK_STEP.WAIT_AGV_REACH_A5A6);
runInfo= "空料架从产线 [" + EmptyShelfPlace + "] 送往双层线" + EmptyShelfTargetPlace;
msg += runInfo;
EmptyBackStep.Msg = msg;
Common.MoveToNode(agv, EmptyShelfTargetPlace);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else
{
EmptyBackStep.ToNextStep(EMPTY_SHELF_BACK_STEP.WAIT_AGV_REACH_STANDBY);
runInfo= "双层线暂不需要空料架,从产线[" + EmptyShelfPlace + "]到待机位";
msg += runInfo;
EmptyBackStep.Msg = msg;
Common.MoveToNode(agv, SettingString.Standby);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
}
else if (EmptyBackStep.IsStep(EMPTY_SHELF_BACK_STEP.WAIT_AGV_REACH_STANDBY))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckA5A6State(agv, shelfType, out string nodeName))
{
EmptyShelfTargetPlace = nodeName;
EmptyBackStep.ToNextStep(EMPTY_SHELF_BACK_STEP.WAIT_AGV_REACH_A5A6);
runInfo= "待机位检测到双层线需要料架,送往双层线 " + EmptyShelfTargetPlace;
msg += runInfo;
EmptyBackStep.Msg = msg;
Common.MoveToNode(agv, EmptyShelfTargetPlace);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
else if (EmptyBackStep.IsStep(EMPTY_SHELF_BACK_STEP.WAIT_AGV_REACH_A5A6))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckTaskFinished(agv, EmptyShelfTargetPlace, CurTaskState) && EmptyShelfTargetPlace.StartsWith("A"))
{
//msg = "AGV到达 " + EmptyShelfTargetPlace;
//EmptyBackStep.Msg = msg;
//return new EnterLeaveShelfJob(EmptyShelfTargetPlace,eEnterLeaveType.Leave,shelfType);
EmptyBackStep.ToNextStep(EMPTY_SHELF_BACK_STEP.WAIT_DOUBLE_LINE_RESPONSE);
runInfo= "AGV到达 " + EmptyShelfTargetPlace + ",并发送入料架请求[ReadyEnter]";
msg += runInfo;
EmptyBackStep.Msg = msg;
Common.server.ReadyEnter(EmptyShelfTargetPlace);
}
}
else if (EmptyBackStep.IsStep(EMPTY_SHELF_BACK_STEP.WAIT_DOUBLE_LINE_RESPONSE))
{
int id = Common.FindNode(EmptyShelfTargetPlace);
ClientNode node = Common.nodeInfo[id];
if (node.StateEquals(eNodeStatus.MayEnter))
{
if(!agv.CurTaskName.Equals("Leave"))
{
EmptyBackStep.ToNextStep(EMPTY_SHELF_BACK_STEP.WAIT__EMPTY_SHELF_IN_DOUBLE_LINE);
runInfo = "收到双层线入料架请求[ReadyEnter]的响应 " + EmptyShelfTargetPlace + "入料架,小车链条运行";
msg += runInfo;
EmptyBackStep.Msg = msg;
rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission["Leave"]);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
else if (EmptyBackStep.IsTimeOut(15000, out double timeOutValue))
{
tryTimes++;
if (tryTimes < 5)
return this;
// if(EmptyShelfTargetPlace.Equals(SettingString.A6))
// {
tryTimes = 0;
EmptyBackStep.ToNextStep(EMPTY_SHELF_BACK_STEP.WAIT_AGV_REACH_STANDBY);
runInfo = "双层线"+ EmptyShelfTargetPlace + "暂不需要空料架,从[" + EmptyShelfTargetPlace + "]到待机位";
msg += runInfo;
EmptyBackStep.Msg = msg;
Common.MoveToNode(agv, SettingString.Standby);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
// }
//else if(EmptyShelfTargetPlace.Equals(SettingString.A5))
//{
// tryTimes = 0;
// EmptyBackStep.ToNextStep(EMPTY_SHELF_BACK_STEP.WAIT_AGV_REACH_STANDBY);
// runInfo = "双层线A5暂不需要空料架,从[" + EmptyShelfTargetPlace + "]到待机位";
// msg += runInfo;
// EmptyBackStep.Msg = msg;
// Common.MoveToNode(agv, SettingString.Standby);
// UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
//}
//else
//{
// EmptyBackStep.ToNextStep(EMPTY_SHELF_BACK_STEP.WAIT_AGV_REACH_A5A6);
//}
// EmptyBackStep.ToNextStep(EMPTY_SHELF_BACK_STEP.WAIT_AGV_REACH_A5A6);
//runInfo= "AGV到达 " + EmptyShelfTargetPlace + ",15秒后重新向双层线发送入料架请求[ReadyEnter]";
//msg += runInfo;
//EmptyBackStep.Msg = msg;
}
}
else if (EmptyBackStep.IsStep(EMPTY_SHELF_BACK_STEP.WAIT__EMPTY_SHELF_IN_DOUBLE_LINE))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckEnterOrLeaveFinished(agv,"Leave",CurTaskState))
{
//EmptyBackStep.ToNextStep(EMPTY_SHELF_BACK_STEP.END);
agv.RFID = "";
Job job = Common.control.GetJob(agv);
if (job != null)
{
runInfo= "在双层线检测到任务,执行任务";
msg += runInfo;
EmptyBackStep.Msg = msg;
return job;
}
else
{
runInfo= "空料架进入" + EmptyShelfTargetPlace + "完成,暂无任务,回充电位";
msg += runInfo;
EmptyBackStep.Msg = msg;
agv.RFID = "";
agv.BoxDestInfo = "";
return new ChargeJob(SettingString.DoubleLine_Name_Prefix);
}
}
else if (EmptyBackStep.IsTimeOut(60000, out double timeOutValue))
{
//链条停止
runInfo= "空料架在[" + EmptyShelfTargetPlace + "]离开小车超时[" + timeOutValue.ToString("f1") + "秒],请检查料架离开小车的情况";
//msg += runInfo;
//EmptyBackStep.Msg = msg;
}
}
else if (EmptyBackStep.IsStep(EMPTY_SHELF_BACK_STEP.END))
{
}
return this;
}
/// <summary>
/// AGV载空料架回收流程
/// </summary>
private enum EMPTY_SHELF_BACK_STEP
{
/// <summary>
/// 料架已进入小车,寻找目的地
/// </summary>
NONE,
/// <summary>
/// 等待AGV到达门
/// </summary>
WAIT_AGV_REACH_DOOR,
/// <summary>
/// 等待小车到达A5,A6
/// </summary>
WAIT_AGV_REACH_A5A6,
/// <summary>
/// 等待双层线回应
/// </summary>
WAIT_DOUBLE_LINE_RESPONSE,
/// <summary>
/// 等待料架进入双层线
/// </summary>
WAIT__EMPTY_SHELF_IN_DOUBLE_LINE,
/// <summary>
/// A5,A6暂时不需要,等待AGV到达待机位
/// </summary>
WAIT_AGV_REACH_STANDBY,
/// <summary>
/// 送上双层线
/// </summary>
END
}
}
}

using AGVControl;
using BLL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
namespace AGVControl
{
/// <summary>
/// 小车进出料类型
/// </summary>
public enum eEnterLeaveType
{
/// <summary>
/// 小车进料
/// </summary>
Enter,
/// <summary>
/// 小车出料
/// </summary>
Leave,
}
/// <summary>
/// 进出料任务
/// </summary>
public class EnterLeaveShelfJob : Job
{
/// <summary>
/// 进出料任务
/// </summary>
/// <param name="palce">位置点名称</param>
/// <param name="rfid">RFID</param>
public EnterLeaveShelfJob(string palce, eEnterLeaveType type,eShelfType shelfType= eShelfType.SmallShelf,string rfid="")
{
LineName = palce;
RFID = rfid;
ActionType = type;
this.shelfType = shelfType;
}
/// <summary>
/// 位置名
/// </summary>
public new string LineName { get; set; }
public string RFID { get; set; }
public eEnterLeaveType ActionType { get; set; }
private eShelfType shelfType;
private string runInfo = "";
/// <summary>
/// 运行信息
/// </summary>
public override string RunInfo
{
get { return runInfo; }
}
private JobStep<ENTER_LEAVE_SHELF_STEP> EnterLeaveShelfStep = new JobStep<ENTER_LEAVE_SHELF_STEP>(ENTER_LEAVE_SHELF_STEP.NONE);
public override Job Execute(Agv_Info agv)
{
string msg = agv.Name+ " ";
bool rtn = false;
agv.Msg = runInfo;
//if (!CurTaskID.Equals(-1) && Common.mir.Get_Task_State(CurTaskID, out string st))
// CurTaskState = st;
if (EnterLeaveShelfStep.IsStep(ENTER_LEAVE_SHELF_STEP.NONE))
{
if (ActionType.Equals(eEnterLeaveType.Leave))
{
//EnterLeaveShelfStep.ToNextStep(ENTER_LEAVE_SHELF_STEP.WAIT_LINE_ReadyEnter_RESPONSE);
//msg = "AGV到达 " + LineName + ",并发送入料架请求[ReadyEnter]";
//EnterLeaveShelfStep.Msg = msg;
//Common.server.ReadyEnter(LineName);
EnterLeaveShelfStep.ToNextStep(ENTER_LEAVE_SHELF_STEP.WAIT__SHELF_IN_LINE);
runInfo = LineName + "入料架,小车链条运行";
msg += runInfo;
EnterLeaveShelfStep.Msg = msg;
rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission["Leave"]);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else if(ActionType.Equals(eEnterLeaveType.Enter))
{
//EnterLeaveShelfStep.ToNextStep(ENTER_LEAVE_SHELF_STEP.WAIT_LINE_ReadyLeave_RESPONSE);
//msg = "AGV到达 " + LineName + ",并发送出料架请求[ReadyLeave]";
//EnterLeaveShelfStep.Msg = msg;
//Common.server.ReadyLeave(LineName);
EnterLeaveShelfStep.ToNextStep(ENTER_LEAVE_SHELF_STEP.WAIT__SHELF_OUT_LINE);
runInfo = LineName + "出料架,小车链条运行";
msg += runInfo;
EnterLeaveShelfStep.Msg = msg;
rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission["Enter"]);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
else if (EnterLeaveShelfStep.IsStep(ENTER_LEAVE_SHELF_STEP.WAIT_LINE_ReadyEnter_RESPONSE))
{
int id = Common.FindNode(LineName);
ClientNode node = Common.nodeInfo[id];
if (node.StateEquals(eNodeStatus.MayEnter))
{
EnterLeaveShelfStep.ToNextStep(ENTER_LEAVE_SHELF_STEP.WAIT__SHELF_IN_LINE);
runInfo= "收到产线入料架请求[ReadyEnter]的响应, " + LineName + "入料架,小车链条运行";
msg += runInfo;
EnterLeaveShelfStep.Msg = msg;
rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission["Leave"]);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else if (EnterLeaveShelfStep.IsTimeOut(15000, out double timeOutValue))
{
EnterLeaveShelfStep.ToNextStep(ENTER_LEAVE_SHELF_STEP.NONE);
runInfo = "AGV到达 " + LineName + ",15秒后重新向产线发送入料架请求[ReadyEnter]";
msg += runInfo;
EnterLeaveShelfStep.Msg = msg;
}
}
else if (EnterLeaveShelfStep.IsStep(ENTER_LEAVE_SHELF_STEP.WAIT_LINE_ReadyLeave_RESPONSE))
{
int id = Common.FindNode(LineName);
ClientNode node = Common.nodeInfo[id];
if (node.StateEquals(eNodeStatus.MayLeave))
{
EnterLeaveShelfStep.ToNextStep(ENTER_LEAVE_SHELF_STEP.WAIT__SHELF_OUT_LINE);
runInfo= "收到产线出料架请求[ReadyLeave]的响应, " + LineName + "出料架,小车链条运行";
msg += runInfo;
EnterLeaveShelfStep.Msg = msg;
rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission["Enter"]);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else if (EnterLeaveShelfStep.IsTimeOut(15000, out double timeOutValue))
{
EnterLeaveShelfStep.ToNextStep(ENTER_LEAVE_SHELF_STEP.NONE);
runInfo= "AGV到达 " + LineName + ",15秒后重新向产线发送入料架请求[ReadyLeave]";
msg += runInfo;
EnterLeaveShelfStep.Msg = msg;
}
}
else if (EnterLeaveShelfStep.IsStep(ENTER_LEAVE_SHELF_STEP.WAIT__SHELF_IN_LINE))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckEnterOrLeaveFinished(agv, "Leave", CurTaskState))
{
//EnterLeaveShelfStep.ToNextStep(ENTER_LEAVE_SHELF_STEP.END);
runInfo= "料架进入" + LineName + "完成 [" + RFID + "]";
msg += runInfo;
EnterLeaveShelfStep.Msg = msg;
agv.RFID = "";
return new EmptyAGVBackJob(LineName);
}
else if (EnterLeaveShelfStep.IsTimeOut(60000, out double timeOutValue))
{
//链条停止
runInfo= "料架在[" + LineName + "]离开小车超时[" + timeOutValue.ToString("f1") + "秒],请检查料架离开小车的情况";
//msg += runInfo;
//EnterLeaveShelfStep.Msg = msg;
}
}
else if (EnterLeaveShelfStep.IsStep(ENTER_LEAVE_SHELF_STEP.WAIT__SHELF_OUT_LINE))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckEnterOrLeaveFinished(agv, "Enter", CurTaskState))
{
//EnterLeaveShelfStep.ToNextStep(ENTER_LEAVE_SHELF_STEP.END);
runInfo = "料架在" + LineName + "出去完成 [" + RFID + "]";
msg += runInfo;
EnterLeaveShelfStep.Msg = msg;
Common.DelEmptyShelfTask(LineName);
return new EmptyShelfBackJob(LineName,eShelfType.BigShelf);
}
else if (EnterLeaveShelfStep.IsTimeOut(60000, out double timeOutValue))
{
//链条停止
runInfo= "料架在[" + LineName + "]进入小车超时[" + timeOutValue.ToString("f1") + "秒],请检查料架进入小车的情况";
//msg += runInfo;
//EnterLeaveShelfStep.Msg = msg;
}
}
else if (EnterLeaveShelfStep.IsStep(ENTER_LEAVE_SHELF_STEP.END))
{
}
return this;
}
}
/// <summary>
/// AGV进出料
/// </summary>
public enum ENTER_LEAVE_SHELF_STEP
{
/// <summary>
///
/// </summary>
NONE,
/// <summary>
/// 等待产线ReadyEnter回应
/// </summary>
WAIT_LINE_ReadyEnter_RESPONSE,
/// <summary>
/// 等待产线ReadyLeave回应
/// </summary>
WAIT_LINE_ReadyLeave_RESPONSE,
/// <summary>
/// 等待料架离开产线
/// </summary>
WAIT__SHELF_OUT_LINE,
/// <summary>
/// 等待料架进入产线
/// </summary>
WAIT__SHELF_IN_LINE,
/// <summary>
/// 进入/离开完成
/// </summary>
END
}
}

using AGVControl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AGVControl
{
/// <summary>
/// 去空料架任务点
/// </summary>
public class GoEmptyShelfLineJob : Job
{
/// <summary>
/// 去空料架任务点
/// </summary>
/// <param name="agvPlae">小车当前位置,空表示在待机位</param>
/// <param name="palce">空料架位置点</param>
public GoEmptyShelfLineJob(string agvPlae, string palce)
{
EmptyShelfPlace = palce;
this.agvPlae = agvPlae;
}
/// <summary>
/// 空料架位置点
/// </summary>
public string EmptyShelfPlace { get; set; }
/// <summary>
/// 接收任务时,agv的位置
/// </summary>
private string agvPlae { get; set; }
private string runInfo = "";
/// <summary>
/// 运行信息
/// </summary>
public override string RunInfo
{
get { return runInfo; }
}
private JobStep<TAKE_EMPTY_STEP> TakeEmptyStep = new JobStep<TAKE_EMPTY_STEP>(TAKE_EMPTY_STEP.NONE);
/// <summary>
/// 空架任务执行,去目的地
/// </summary>
/// <param name="agv"></param>
public override Job Execute(Agv_Info agv)
{
string msg = agv.Name + " ";
bool rtn = false;
agv.Msg = runInfo;
int nodeIdx = Common.FindNode(EmptyShelfPlace);
//if (!CurTaskID.Equals(-1) && Common.mir.Get_Task_State(CurTaskID, out string st))
// CurTaskState = st;
if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.NONE))
{
if (agvPlae.StartsWith(SettingString.C4_Name_Prefix) && EmptyShelfPlace.StartsWith(SettingString.D4_Name_Prefix))//4C->4D
{
TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_AGV_REACH_4D_DOOR);
runInfo = "去空料架产线" + EmptyShelfPlace + ",先前往4D门[" + agvPlae + "->" + EmptyShelfPlace + "]";
msg += runInfo;
TakeEmptyStep.Msg = msg;
Common.DoorMission(agv, SettingString.DoorCToD);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else if ((agvPlae.StartsWith(SettingString.D4_Name_Prefix) || agvPlae.StartsWith("A") || agvPlae.Equals(SettingString.Standby) || agvPlae.Equals(SettingString.AutoCharge))
&& EmptyShelfPlace.StartsWith(SettingString.C4_Name_Prefix))//4D->4C
{
TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_AGV_REACH_4C_DOOR);
runInfo= "去空料架产线" + EmptyShelfPlace + ",先前往4C门[" + agvPlae + "->" + EmptyShelfPlace + "]";
msg += runInfo;
TakeEmptyStep.Msg = msg;
Common.DoorMission(agv, SettingString.DoorDToC);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else if(agvPlae.StartsWith(SettingString.C4_Name_Prefix) && EmptyShelfPlace.StartsWith(SettingString.C4_Name_Prefix))
{
if(Common.Check4CTarget(agv, EmptyShelfPlace))//被占用
{
TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_REACH_TEMP_PLACE);
runInfo = "目的地" + EmptyShelfPlace + "有小车占用,先到临时待机位";
msg += runInfo;
TakeEmptyStep.Msg = msg;
Common.MoveTo4CStandy(agv);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else
{
TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.ASSIGN_AGV_TASK);
runInfo = "开始执行回收空料架任务[" + agvPlae + "->" + EmptyShelfPlace + "]";
msg += runInfo;
TakeEmptyStep.Msg = msg;
}
}
else
{
TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.ASSIGN_AGV_TASK);
runInfo= "开始执行回收空料架任务[" + agvPlae + "->" + EmptyShelfPlace + "]";
msg += runInfo;
TakeEmptyStep.Msg = msg;
}
}
else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.WAIT_AGV_REACH_4C_DOOR))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckTaskFinished(agv, SettingString.DoorDToC, CurTaskState))
{
if (Common.Check4CTarget(agv, EmptyShelfPlace))//被占用
{
TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_REACH_TEMP_PLACE);
runInfo = "目的地" + EmptyShelfPlace + "有小车占用,先到临时待机位";
msg += runInfo;
TakeEmptyStep.Msg = msg;
Common.MoveTo4CStandy(agv);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else
{
TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.ASSIGN_AGV_TASK);
runInfo = "开始执行回收空料架任务[" + agvPlae + "->" + EmptyShelfPlace + "]";
msg += runInfo;
TakeEmptyStep.Msg = msg;
}
}
}
else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.WAIT_REACH_TEMP_PLACE))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckTaskFinished(agv, SettingString.C4_STANDBY1, CurTaskState) || Common.CheckTaskFinished(agv, SettingString.C4_STANDBY2, CurTaskState))
{
if (!Common.Check4CTarget(agv, EmptyShelfPlace))//未占用
{
TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.ASSIGN_AGV_TASK);
runInfo = "开始执行回收空料架任务[" + agvPlae + "->" + EmptyShelfPlace + "]";
msg += runInfo;
TakeEmptyStep.Msg = msg;
Common.DeleteStandyInfo(agv);
}
}
}
else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.WAIT_AGV_REACH_4D_DOOR))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckTaskFinished(agv, SettingString.DoorCToD, CurTaskState))
{
TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.ASSIGN_AGV_TASK);
runInfo = "开始执行回收空料架任务[" + agvPlae + "->" + EmptyShelfPlace + "]";
msg += runInfo;
TakeEmptyStep.Msg = msg;
}
}
else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.ASSIGN_AGV_TASK))
{
if (nodeIdx > -1)
{
TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_AGV_START_TASK);
runInfo= "AGV 添加任务:移动到" + EmptyShelfPlace;
msg += runInfo;
TakeEmptyStep.Msg = msg;
Common.MoveToNode(agv, EmptyShelfPlace);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else
{
TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.ASSIGN_AGV_TASK);
runInfo= EmptyShelfPlace + " 不存在或未开启调用";
msg += runInfo;
TakeEmptyStep.Msg = msg;
}
}
else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.WAIT_AGV_START_TASK))
{
if (agv.CurTaskState.Equals(SettingString.Executing))
{
TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_REACH_PLACE);
runInfo= "AGV开始向目的地[" + EmptyShelfPlace + "]移动";
msg += runInfo;
TakeEmptyStep.Msg = msg;
}
}
else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.WAIT_REACH_PLACE))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckTaskFinished(agv, EmptyShelfPlace, CurTaskState))
{
//if (EmptyShelfPlace.Equals(SettingString.C4FeederOut))
//{
// runInfo = "AGV到达 " + EmptyShelfPlace;
// msg += runInfo;
// TakeEmptyStep.Msg = msg;
// return new EnterLeaveShelfJob(EmptyShelfPlace, eEnterLeaveType.Enter);
//}
//else
{
TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_LINE_RESPONSE);
runInfo= "AGV到达 " + EmptyShelfPlace + " 向产线发送出料架请求[ReadyLeave]";
msg += runInfo;
TakeEmptyStep.Msg = msg;
if (nodeIdx == -1)
{
runInfo = EmptyShelfPlace + " 未开启调用";
msg += runInfo;
TakeEmptyStep.Msg = msg;
return this;
}
ClientNode node = Common.nodeInfo[nodeIdx];
agv.RFID = node.RFID;
Common.server.ReadyLeave(EmptyShelfPlace);
}
}
}
else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.WAIT_LINE_RESPONSE))
{
if(nodeIdx==-1)
{
runInfo= EmptyShelfPlace + " 未开启调用";
msg += runInfo;
TakeEmptyStep.Msg = msg;
return this;
}
ClientNode node = Common.nodeInfo[nodeIdx];
agv.RFID = node.RFID;
if (node.StateEquals(eNodeStatus.MayLeave))
{
if (!agv.CurTaskName.Equals("Enter"))
{
TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_TAKE_EMPTY_SHELF);
runInfo = "收到产线出料请求[ReadyLeave]的响应 " + EmptyShelfPlace + "出料架,小车链条运行";
msg += runInfo;
TakeEmptyStep.Msg = msg;
//agv.RFID = node.RFID;
rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission["Enter"]);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
else if (TakeEmptyStep.IsTimeOut(15000, out double timeOutValue))
{
TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_REACH_PLACE);
//runInfo = "AGV到达 " + EmptyShelfPlace + ",15秒后重新向产线发送出料架请求[ReadyLeave]";
//msg += runInfo;
//TakeEmptyStep.Msg = msg;
}
}
else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.WAIT_TAKE_EMPTY_SHELF))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckEnterOrLeaveFinished(agv, "Enter", CurTaskState))
{
ClientNode node = Common.nodeInfo[nodeIdx];
node.AgvName = "";
//回收空料架数量减少1
Common.DelEmptyShelfTask(EmptyShelfPlace);
runInfo= "空料架在[" + EmptyShelfPlace + "]进入小车完成";
msg += runInfo;
TakeEmptyStep.Msg = msg;
//4DfeederOut默认大料架
if (agv.Place.Equals(SettingString.D4FeederOut))
return new EmptyShelfBackJob(EmptyShelfPlace, eShelfType.BigShelf);
if (agv.Place.Equals(SettingString.C4FeederOut))
return new EmptyShelfBackJob(EmptyShelfPlace, eShelfType.BigShelf);
else if (agv.RFID.StartsWith("D"))
return new EmptyShelfBackJob(EmptyShelfPlace, eShelfType.SmallShelf);
else if (agv.RFID.StartsWith("C"))
{
return new EmptyShelfBackJob(EmptyShelfPlace, eShelfType.BigShelf);
}
else
return new EmptyShelfBackJob(EmptyShelfPlace, eShelfType.SmallShelf);
}
else if (TakeEmptyStep.IsTimeOut(60000, out double timeOutValue))
{
//链条停止
runInfo = "空料架在[" + EmptyShelfPlace + "]进入小车超时[" + timeOutValue.ToString("f1") + "秒],请检查料架进入小车的情况";
// msg += runInfo;
//TakeEmptyStep.Msg = msg;
}
}
else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.END))
{
}
return this;
}
/// <summary>
/// AGV回收空料架流程
/// </summary>
private enum TAKE_EMPTY_STEP
{
/// <summary>
/// 准备,发送给AGV
/// </summary>
NONE,
/// <summary>
/// 等待到达4C门
/// </summary>
WAIT_AGV_REACH_4C_DOOR,
/// <summary>
/// 等待到达4D门
/// </summary>
WAIT_AGV_REACH_4D_DOOR,
/// <summary>
/// 给AGV分配任务
/// </summary>
ASSIGN_AGV_TASK,
/// <summary>
/// 等待AGV开始执行去取架点任务
/// </summary>
WAIT_AGV_START_TASK,
/// <summary>
/// 等待AGV到达取架点
/// </summary>
WAIT_REACH_PLACE,
/// <summary>
/// 等待AGV到达临时停车位
/// </summary>
WAIT_REACH_TEMP_PLACE,
/// <summary>
/// 等待产线回应
/// </summary>
WAIT_LINE_RESPONSE,
/// <summary>
/// 等待料架进入小车
/// </summary>
WAIT_TAKE_EMPTY_SHELF,
/// <summary>
/// 料架进入小车完成
/// </summary>
END
}
}
}

using AGVControl;
using BLL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AGVControl
{
/// <summary>
/// 检查AGV是否有负载,去A6入料口并装车
/// </summary>
public class GoFullShelfStationJob : Job
{
/// <summary>
/// 去A6入料口任务并检查AGV是否有负载
/// </summary>
/// <param name="agvCurPlace">接到任务时,AGV的位置(空表示待机位)</param>
/// <param name="palce"></param>
public GoFullShelfStationJob(string agvCurPlace = "", string palce = "A6")
{
FullShelfStationPlace = palce;
agvPlace = agvCurPlace;
}
/// <summary>
/// 出满料位置点
/// </summary>
public string FullShelfStationPlace { get; set; }
/// <summary>
/// 接到任务时,AGV的位置
/// </summary>
public string agvPlace { get; set; }
private string runInfo = "";
/// <summary>
/// 运行信息
/// </summary>
public override string RunInfo
{
get { return runInfo; }
}
/// <summary>
/// AGV上是否有负载
/// </summary>
public bool IsLoadOnAGV { get; private set; } = false;
public AGVManager.BoxDestInfo FullShelfDestInfo = null;
private JobStep<GO_FULL_SHELF_STATION_STEP> GoFullShelfStationStep = new JobStep<GO_FULL_SHELF_STATION_STEP>(GO_FULL_SHELF_STATION_STEP.NONE);
public override Job Execute(Agv_Info agv)
{
string msg = agv.Name + " ";
bool rtn = false;
agv.Msg = runInfo;
//if (!CurTaskID.Equals(-1) && Common.mir.Get_Task_State(CurTaskID, out string st))
// CurTaskState = st;
if (GoFullShelfStationStep.IsStep(GO_FULL_SHELF_STATION_STEP.NONE))
{
GoFullShelfStationStep.ToNextStep(GO_FULL_SHELF_STATION_STEP.WAIT_CHECK_RESULT);
runInfo = "检查AGV负载情况";
msg += runInfo;
GoFullShelfStationStep.Msg = msg;
Common.CheckLoad(agv);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else if (GoFullShelfStationStep.IsStep(GO_FULL_SHELF_STATION_STEP.WAIT_CHECK_RESULT))
{
//Common.log.Debug("WAIT_CHECK_RESULT " + Common.agvMission["CheckShelf"].Equals(agv.CurTaskGUID).ToString() + " " + agv.CurTaskGUID + " " + Common.agvMission["CheckShelf"]);
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.agvMission["CheckShelf"].Equals(agv.CurTaskGUID) && agv.CurTaskState.Equals(SettingString.Done))
{
rtn = Common.mir.Get_IO_Status(agv, out bool[] input, out bool[] output);
if (rtn)
{
Common.log.Debug("WAIT_CHECK_RESULT: " + agv.Name + " 获取IO状态成功:满载信号=" + input[3].ToString());
if (input != null && input[3])
{
GoFullShelfStationStep.ToNextStep(GO_FULL_SHELF_STATION_STEP.END);
runInfo = "车上有料架,无法去入料口出料";
msg += runInfo;
GoFullShelfStationStep.Msg = msg;
agv.IsExistShelf = true;
IsLoadOnAGV = true;
}
else if (input != null && !input[3])
{
if (agvPlace.Equals(SettingString.Standby) || agvPlace.StartsWith(SettingString.AutoCharge))//待机位/充电位接到任务
{
GoFullShelfStationStep.ToNextStep(GO_FULL_SHELF_STATION_STEP.WAIT_AGV_REACH_A6);
runInfo = "无负载,准备运动到入料口" + FullShelfStationPlace;
msg += runInfo;
GoFullShelfStationStep.Msg = msg;
Common.MoveToNode(agv, FullShelfStationPlace);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else if (agvPlace.StartsWith(SettingString.C4_Name_Prefix))//4C车间
{
GoFullShelfStationStep.ToNextStep(GO_FULL_SHELF_STATION_STEP.WAIT_AGV_REACH_DOOR);
runInfo = "在4C车间,向4D门运行,再到双层线入料口";
msg += runInfo;
GoFullShelfStationStep.Msg = msg;
Common.DoorMission(agv, SettingString.DoorCToD);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else
{
GoFullShelfStationStep.ToNextStep(GO_FULL_SHELF_STATION_STEP.WAIT_AGV_REACH_A6);
runInfo = "无负载,准备运动到入料口" + FullShelfStationPlace;
msg += runInfo;
GoFullShelfStationStep.Msg = msg;
Common.MoveToNode(agv, FullShelfStationPlace);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
}
else
{
Common.LogInfo("WAIT_CHECK_RESULT: 获取IO状态失败,使用小车IO信号");
if (!agv.IsExistShelf)
{
if (agvPlace.Equals(""))//待机位接到任务
{
GoFullShelfStationStep.ToNextStep(GO_FULL_SHELF_STATION_STEP.WAIT_AGV_REACH_A6);
runInfo = "无负载,准备运动到入料口" + FullShelfStationPlace;
msg = runInfo;
GoFullShelfStationStep.Msg = msg;
Common.MoveToNode(agv, FullShelfStationPlace);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else if (agvPlace.StartsWith(SettingString.C4_Name_Prefix))//4C车间
{
GoFullShelfStationStep.ToNextStep(GO_FULL_SHELF_STATION_STEP.WAIT_AGV_REACH_DOOR);
runInfo = "在4C车间,向4D门运行,再到双层线入料口";
msg += runInfo;
GoFullShelfStationStep.Msg = msg;
Common.DoorMission(agv, SettingString.DoorCToD);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
}
}
}
else if (GoFullShelfStationStep.IsStep(GO_FULL_SHELF_STATION_STEP.WAIT_AGV_REACH_DOOR))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckTaskFinished(agv, SettingString.DoorCToD, CurTaskState))
{
GoFullShelfStationStep.ToNextStep(GO_FULL_SHELF_STATION_STEP.WAIT_AGV_REACH_A6);
runInfo = "到达4D门,准备运动到双层线入料口" + FullShelfStationPlace;
msg += runInfo;
GoFullShelfStationStep.Msg = msg;
Common.MoveToNode(agv, FullShelfStationPlace);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
else if (GoFullShelfStationStep.IsStep(GO_FULL_SHELF_STATION_STEP.WAIT_AGV_REACH_A6))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckTaskFinished(agv, FullShelfStationPlace, CurTaskState))
{
ClientNode node = Common.nodeInfo.Find(s => s.Name.Equals(SettingString.A6)
&& (s.StateEquals(eNodeStatus.NeedLeave) || s.StateEquals(eNodeStatus.NeedEnterLeave)) && !s.RFID.Equals("00"));
if (node != null && node.Name.Equals(SettingString.A6))
{
if (AGVManager.FindFullShelfTarget(node.RFID, out FullShelfDestInfo))
{
GoFullShelfStationStep.ToNextStep(GO_FULL_SHELF_STATION_STEP.WAIT_DOUBLE_LINE_RESPONSE);
if (FullShelfDestInfo!=null)
{
Common.GetLineNameByNodeName(FullShelfDestInfo.location,out string line);
agv.BoxDestInfo = FullShelfDestInfo.ShowInfo(line);
}
runInfo = "AGV到达 " + FullShelfStationPlace + ",并发送出料架请求[ReadyLeave]";
msg += runInfo;
GoFullShelfStationStep.Msg = msg;
Common.server.ReadyLeave(FullShelfStationPlace);
}
else
{
if (FullShelfDestInfo !=null)
{
Common.GetLineNameByNodeName(FullShelfDestInfo.location, out string line);
runInfo = "AGV到达 " + FullShelfStationPlace + ",查询满料架目的地:" + FullShelfDestInfo.ShowInfo(line);
msg += runInfo; ;
GoFullShelfStationStep.Msg = msg;
}
else
{
//[{"msg":"0料车已解绑或未发新料"}]
GoFullShelfStationStep.ToNextStep(GO_FULL_SHELF_STATION_STEP.WAIT_REACH_STANDBY);
runInfo = "从产线" + agvPlace + "回到待机位";
msg += runInfo;
GoFullShelfStationStep.Msg = msg;
Common.MoveToNode(agv, SettingString.Standby);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
}
}
//else if (GoFullShelfStationStep.IsTimeOut(30000, out double timeOutValue) && !agv.TaskSend.Equals(SettingString.Move + SettingString.A6)
// && !agv.CurTaskName.Equals(SettingString.Move+SettingString.A6))
//{
// Common.MoveToNode(agv, FullShelfStationPlace);
//}
}
else if (GoFullShelfStationStep.IsStep(GO_FULL_SHELF_STATION_STEP.WAIT_REACH_STANDBY))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckTaskFinished(agv, SettingString.Standby, CurTaskState))
{
GoFullShelfStationStep.ToNextStep(GO_FULL_SHELF_STATION_STEP.END);
runInfo = "到达待机位";
msg += runInfo;
GoFullShelfStationStep.Msg = msg;
}
}
else if (GoFullShelfStationStep.IsStep(GO_FULL_SHELF_STATION_STEP.WAIT_DOUBLE_LINE_RESPONSE))
{
int id = Common.FindNode(FullShelfStationPlace);
if (id == -1)
{
runInfo = "未找到节点:" + FullShelfStationPlace;
msg += runInfo;
GoFullShelfStationStep.Msg = msg;
return this;
}
ClientNode node = Common.nodeInfo[id];
if (node.StateEquals(eNodeStatus.MayLeave))
{
if (!agv.CurTaskName.Equals("Enter"))
{
GoFullShelfStationStep.ToNextStep(GO_FULL_SHELF_STATION_STEP.WAIT__FULL_SHELF_IN_AGV);
runInfo = "收到双层线出料架请求[ReadyLeave]的响应 " + FullShelfStationPlace + "出料架,小车链条运行";
msg += runInfo;
GoFullShelfStationStep.Msg = msg;
rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission["Enter"]);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
else if (GoFullShelfStationStep.IsTimeOut(15000, out double timeOutValue))
{
GoFullShelfStationStep.ToNextStep(GO_FULL_SHELF_STATION_STEP.WAIT_AGV_REACH_A6);
//runInfo = "AGV到达 " + FullShelfStationPlace + ",15秒后重新向双层线发送出料架请求[ReadyLeave]";
//msg += runInfo;
//GoFullShelfStationStep.Msg = msg;
}
}
else if (GoFullShelfStationStep.IsStep(GO_FULL_SHELF_STATION_STEP.WAIT__FULL_SHELF_IN_AGV))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckEnterOrLeaveFinished(agv, "Enter", CurTaskState))
{
//GoFullShelfStationStep.ToNextStep(GO_FULL_SHELF_STATION_STEP.END);
runInfo = FullShelfStationPlace + "满料架进入小车完成";
msg += runInfo;
GoFullShelfStationStep.Msg = msg;
//if (FullShelfDestInfo.location.StartsWith("G"))
//{
// return new SendFullShelfToLineJob(FullShelfDestInfo, true);
//}
//else
return new SendFullShelfToLineJob(FullShelfDestInfo);
}
else if (GoFullShelfStationStep.IsTimeOut(60000, out double timeOutValue))
{
//链条停止
runInfo= "满料架在[" + FullShelfStationPlace + "]进入小车超时[" + timeOutValue.ToString("f1") + "秒],请检查料架进入小车的情况";
//msg +=runInfo;
//GoFullShelfStationStep.Msg = msg;
}
}
return this;
}
}
/// <summary>
/// 出满料步骤
/// </summary>
public enum GO_FULL_SHELF_STATION_STEP
{
/// <summary>
/// 负载检查
/// </summary>
NONE,
/// <summary>
/// 负载检查结果
/// </summary>
WAIT_CHECK_RESULT,
/// <summary>
/// 等待AGV到达门
/// </summary>
WAIT_AGV_REACH_DOOR,
/// <summary>
/// 等待到达A6
/// </summary>
WAIT_AGV_REACH_A6,
/// <summary>
/// 等待双层线回应
/// </summary>
WAIT_DOUBLE_LINE_RESPONSE,
/// <summary>
/// 等待料架进入小车
/// </summary>
WAIT__FULL_SHELF_IN_AGV,
/// <summary>
/// 等待AGV到达待机位
/// </summary>
WAIT_REACH_STANDBY,
/// <summary>
/// 送上双层线
/// </summary>
END
}
}

using AGVControl;
using BLL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
namespace AGVControl
{
/// <summary>
/// 从A6向产线运行任务(出满料)
/// </summary>
public class SendFullShelfToLineJob : Job
{
/// <summary>
/// 从A6向产线运行任务(出满料)
/// </summary>
/// <param name="palce">产线名</param>
/// <param name="rfid">料架RFID</param>
/// <param name="isIgNoreBigShelf">是否忽略大料架</param>
public SendFullShelfToLineJob(AGVManager.BoxDestInfo boxDestInfo, bool isIgNoreBigShelf = false)
{
FullShelfPlace = boxDestInfo.location;
RFID = boxDestInfo.id;
BoxDestInfo = boxDestInfo;
IsIgnoreBigShelf = isIgNoreBigShelf;
}
/// <summary>
/// 满料架目标位置点
/// </summary>
public string FullShelfPlace { get; set; }
public string RFID { get; set; }
public AGVManager.BoxDestInfo BoxDestInfo { get; private set; }
/// <summary>
/// 是否忽略大料架移库解绑
/// </summary>
public bool IsIgnoreBigShelf { get; private set; }
private string runInfo = "";
/// <summary>
/// 运行信息
/// </summary>
public override string RunInfo
{
get { return runInfo; }
}
private JobStep<SEND_FULL_SHELF_STEP> SendFullShelfStep = new JobStep<SEND_FULL_SHELF_STEP>(SEND_FULL_SHELF_STEP.NONE);
public override Job Execute(Agv_Info agv)
{
string msg = agv.Name + " ";
bool rtn = false;
agv.RFID = RFID;
agv.Msg = runInfo;
//if (!CurTaskID.Equals(-1) && Common.mir.Get_Task_State(CurTaskID, out string st))
// CurTaskState = st;
if (SendFullShelfStep.IsStep(SEND_FULL_SHELF_STEP.NONE))
{
if (FullShelfPlace.StartsWith(SettingString.C4_Name_Prefix))
{
SendFullShelfStep.ToNextStep(SEND_FULL_SHELF_STEP.WAIT_AGV_REACH_DOOR);
runInfo = "满料架前往4C门,从双层线A6送往[" + FullShelfPlace + "][RFID=" + RFID + "]";
msg += runInfo;
SendFullShelfStep.Msg = msg;
Common.DoorMission(agv, SettingString.DoorDToC);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else
{
SendFullShelfStep.ToNextStep(SEND_FULL_SHELF_STEP.WAIT_AGV_REACH_LINE);
runInfo = "满料架从双层线A6送往[" + FullShelfPlace + "][RFID=" + RFID + "]";
msg += runInfo;
SendFullShelfStep.Msg = msg;
Common.MoveToNode(agv, FullShelfPlace);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
else if (SendFullShelfStep.IsStep(SEND_FULL_SHELF_STEP.WAIT_AGV_REACH_DOOR))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckTaskFinished(agv, SettingString.DoorDToC, CurTaskState))
{
if (Common.Check4CTarget(agv, FullShelfPlace))//被占用
{
SendFullShelfStep.ToNextStep(SEND_FULL_SHELF_STEP.WAIT_REACH_TEMP_PLACE);
runInfo = "目的地" + FullShelfPlace + "有小车占用,先到临时待机位";
msg += runInfo;
SendFullShelfStep.Msg = msg;
Common.MoveTo4CStandy(agv);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
else
{
SendFullShelfStep.ToNextStep(SEND_FULL_SHELF_STEP.WAIT_AGV_REACH_LINE);
runInfo = "满料架从双层线A6送往[" + FullShelfPlace + "][RFID=" + RFID + "]";
msg += runInfo;
SendFullShelfStep.Msg = msg;
Common.MoveToNode(agv, FullShelfPlace);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
}
else if (SendFullShelfStep.IsStep(SEND_FULL_SHELF_STEP.WAIT_REACH_TEMP_PLACE))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckTaskFinished(agv, SettingString.C4_STANDBY1, CurTaskState) || Common.CheckTaskFinished(agv, SettingString.C4_STANDBY2, CurTaskState))
{
if (!Common.Check4CTarget(agv, FullShelfPlace))//未占用
{
SendFullShelfStep.ToNextStep(SEND_FULL_SHELF_STEP.WAIT_AGV_REACH_LINE);
runInfo = "满料架从临时待机位送往[" + FullShelfPlace + "][RFID=" + RFID + "]";
msg += runInfo;
SendFullShelfStep.Msg = msg;
Common.DeleteStandyInfo(agv);
Common.MoveToNode(agv, FullShelfPlace);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
}
else if (SendFullShelfStep.IsStep(SEND_FULL_SHELF_STEP.WAIT_AGV_REACH_LINE))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckTaskFinished(agv, FullShelfPlace, CurTaskState))
{
//if (FullShelfPlace.Equals(SettingString.C4FeederIn))
//{
// runInfo = "AGV到达 " + FullShelfPlace + "完成";
// msg += runInfo;
// SendFullShelfStep.Msg = msg;
// return new EnterLeaveShelfJob(FullShelfPlace, eEnterLeaveType.Leave);
//}
if (IsIgnoreBigShelf)
{
SendFullShelfStep.ToNextStep(SEND_FULL_SHELF_STEP.WAIT_LINE_RESPONSE);
runInfo = "AGV到达 " + FullShelfPlace + ",并发送入料架请求[ReadyEnter]";
msg += runInfo;
SendFullShelfStep.Msg = msg;
Common.server.ReadyEnter(FullShelfPlace);
}
else
{
if (RFID.StartsWith("C") && !agv.Place.Equals(SettingString.D4FeederIn) && !agv.Place.Equals(SettingString.C4FeederIn))
{
SendFullShelfStep.ToNextStep(SEND_FULL_SHELF_STEP.WAIT_BIG_SHELF_UNLOCK);
runInfo = "AGV到达 " + FullShelfPlace + ",并等待大料架[" + RFID + "]解绑";
msg += runInfo;
SendFullShelfStep.Msg = msg;
}
else
{
SendFullShelfStep.ToNextStep(SEND_FULL_SHELF_STEP.WAIT_LINE_RESPONSE);
runInfo = "AGV到达 " + FullShelfPlace + ",并发送入料架请求[ReadyEnter]";
msg += runInfo;
SendFullShelfStep.Msg = msg;
Common.server.ReadyEnter(FullShelfPlace);
}
}
}
}
else if (SendFullShelfStep.IsStep(SEND_FULL_SHELF_STEP.WAIT_BIG_SHELF_UNLOCK))
{
Common.mir.Get_IO_Status(agv, out bool[] input, out bool[] output);
System.Threading.Thread.Sleep(50);
if (AGVManager.GetRackBy(RFID, out string lineName) || (input != null && input[0]))
{
runInfo = "大料架在" + FullShelfPlace + "解绑完成 [" + RFID + "] [" + agv.BoxDestInfo + "]";
agv.BoxDestInfo = "";
msg += runInfo;
SendFullShelfStep.Msg = msg;
return new EmptyShelfBackJob(FullShelfPlace, eShelfType.BigShelf);
}
}
else if (SendFullShelfStep.IsStep(SEND_FULL_SHELF_STEP.WAIT_LINE_RESPONSE))
{
int id = Common.FindNode(FullShelfPlace);
ClientNode node = Common.nodeInfo[id];
Common.mir.Get_IO_Status(agv, out bool[] input, out bool[] output);
System.Threading.Thread.Sleep(50);
if (node.StateEquals(eNodeStatus.MayEnter))
{
if (!agv.CurTaskName.Equals("Leave"))
{
SendFullShelfStep.ToNextStep(SEND_FULL_SHELF_STEP.WAIT__SHELF_IN_LINE);
runInfo = "收到产线入料架请求[ReadyEnter]的响应 " + FullShelfPlace + "入料架,小车链条运行";
msg += runInfo;
SendFullShelfStep.Msg = msg;
rtn = Common.mir.Add_Mission_Fleet(agv, Common.agvMission["Leave"]);
UpdateJobTaskInfo(agv.CurTaskName, agv.CurTaskID);
}
}
else if (input != null && !input[3] && input[0])
{
runInfo = "手动操作:满料架进入" + FullShelfPlace + "完成 [RFID=" + RFID + "] [" + agv.BoxDestInfo + "]";
msg += runInfo;
SendFullShelfStep.Msg = msg;
agv.RFID = "";
agv.BoxDestInfo = "";
AGVManager.UpdateStatus(RFID, FullShelfPlace);
return new EmptyAGVBackJob(FullShelfPlace);
}
else if (SendFullShelfStep.IsTimeOut(15000, out double timeOutValue))
{
SendFullShelfStep.ToNextStep(SEND_FULL_SHELF_STEP.WAIT_AGV_REACH_LINE);
runInfo = "AGV到达 " + FullShelfPlace + ",15秒后重新向产线发送入料架请求[ReadyEnter]";
msg += runInfo;
SendFullShelfStep.Msg = msg;
}
}
else if (SendFullShelfStep.IsStep(SEND_FULL_SHELF_STEP.WAIT__SHELF_IN_LINE))
{
CurTaskState = Common.GetTakJobState(CurTaskID);
if (Common.CheckEnterOrLeaveFinished(agv, "Leave", CurTaskState))
{
runInfo = "满料架进入" + FullShelfPlace + "完成 [RFID=" + RFID + "] [" + agv.BoxDestInfo + "]";
msg += runInfo;
SendFullShelfStep.Msg = msg;
agv.RFID = "";
agv.BoxDestInfo = "";
AGVManager.UpdateStatus(RFID, FullShelfPlace);
return new EmptyAGVBackJob(FullShelfPlace);
}
else if (SendFullShelfStep.IsTimeOut(60000, out double timeOutValue))
{
//链条停止
runInfo = "满料架在[" + FullShelfPlace + "]离开小车超时[" + timeOutValue.ToString("f1") + "秒],请检查料架离开小车的情况";
//msg += runInfo;
//SendFullShelfStep.Msg = msg;
}
}
//else if (SendFullShelfStep.IsStep(SEND_FULL_SHELF_STEP.END))
//{
//}
return this;
}
}
/// <summary>
/// AGV送满料架到产线
/// </summary>
public enum SEND_FULL_SHELF_STEP
{
/// <summary>
/// 料架已进入小车,去目的地
/// </summary>
NONE,
/// <summary>
/// 等待AGV到达门
/// </summary>
WAIT_AGV_REACH_DOOR,
/// <summary>
/// 等待agv到达4C临时待机位
/// </summary>
WAIT_REACH_TEMP_PLACE,
/// <summary>
/// 等待小车到达目的地
/// </summary>
WAIT_AGV_REACH_LINE,
/// <summary>
/// 等待大料架解绑
/// </summary>
WAIT_BIG_SHELF_UNLOCK,
/// <summary>
/// 等待AGV载大料架返回双层线
/// </summary>
WAIT_BIG_SHELF_BACK_DOUBLE_LINE,
/// <summary>
/// 等待AGV到达停车位
/// </summary>
WAIT_BIG_SHELF_BACK_STANDYBY,
/// <summary>
/// 等待产线回应
/// </summary>
WAIT_LINE_RESPONSE,
/// <summary>
/// 等待料架进入产线
/// </summary>
WAIT__SHELF_IN_LINE,
/// <summary>
/// 进入产线完成
/// </summary>
END
}
}
文件属性发生变化
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AGVControl
{
/// <summary>
/// 客户端的节点
/// </summary>
public class ClientNode : Node
{
private string rfid = "00";
/// <summary>
/// RFID
/// </summary>
public string RFID
{
set
{
if (value.Length < 2)
rfid = value.PadLeft(2, '0');
else
rfid = value;
}
get
{
return rfid;
}
}
/// <summary>
/// 小车名称
/// </summary>
public string AgvName { set; get; }
/// <summary>
/// 线体名(佳世达)
/// </summary>
public string LineName { set; get; }
/// <summary>
/// 节点位置的guid
/// </summary>
public string Pos_guid { set; get; }
/// <summary>
/// 节点位置名称
/// </summary>
public string Pos_name { get; set; }
public ClientLevel ClientLevel { get; set; } = ClientLevel.Low;
/// <summary>
/// 节点位置坐标
/// </summary>
public PositionStru position;
/// <summary>
/// 空料架数量
/// </summary>
public int EmptyShelfCnt
{
get { return _EmptyShelfCnt; }
set
{
EmptyShelfCnt = _EmptyShelfCnt;
}
}
/// <summary>
/// 空架子的RFID
/// </summary>
public List<string> EmptyShelfRFIDs;
private int _EmptyShelfCnt = 0;
public string AliceName { get; set; }
/// <summary>
/// 客户端节点
/// </summary>
/// <param name="name"></param>
/// <param name="ip"></param>
/// <param name="isUse"></param>
public ClientNode(string name, string ip, string aliceName,string lineName, string pos_name, string pos_guid, bool isUse,int emptyCnt) : base(name, ip, isUse)
{
AliceName = aliceName;
RFID = rfid;
AgvName = "";
Online = false;
IsUse = isUse;
_EmptyShelfCnt = emptyCnt;
this.Pos_name = pos_name;
this.Pos_guid = pos_guid;
LineName = lineName;
EmptyShelfRFIDs = new List<string>();
}
/// <summary>
/// 客户端节点
/// </summary>
/// <param name="name"></param>
/// <param name="rfid"></param>
/// <param name="action"></param>
/// <param name="level"></param>
public ClientNode(string name, string rfid = "", eNodeStatus status = eNodeStatus.None) : base(name)
{
RFID = rfid;
nodeStatus = status;
AgvName = "";
}
/// <summary>
///空料架数量增加,如果RFID相同,不增加数量
/// </summary>
public void IncreEmptyShelfCnt(string rfid="")
{
if(!rfid.Equals("") && !EmptyShelfRFIDs.Contains(rfid))
{
System.Threading.Interlocked.Increment(ref _EmptyShelfCnt);
EmptyShelfRFIDs.Add(rfid);
Common.WriteIni(Name, SettingString.EmptyShelfCnt,_EmptyShelfCnt.ToString());
}
else if(rfid.Equals(""))
{
System.Threading.Interlocked.Increment(ref _EmptyShelfCnt);
Common.WriteIni(Name, SettingString.EmptyShelfCnt, _EmptyShelfCnt.ToString());
}
}
/// <summary>
/// 空料架数量减少1
/// </summary>
public void DecreEmptyShelfCnt()
{
if (_EmptyShelfCnt > 0)
{
System.Threading.Interlocked.Decrement(ref _EmptyShelfCnt);
Common.WriteIni(Name, SettingString.EmptyShelfCnt, _EmptyShelfCnt.ToString());
}
if(_EmptyShelfCnt.Equals(0) && EmptyShelfRFIDs.Count>0)
{
EmptyShelfRFIDs.Clear();
}
}
/// <summary>
/// 节点状态的文本形式
/// </summary>
/// <returns></returns>
public string StatetText()
{
string s = string.Format("[Name={0}, NodeStatus={1}, RFID={2},ClientLevel ={3}]", Name, nodeStatus.ToString(), RFID, ClientLevel.ToString());
return s;
}
public string[] ToRow()
{
//节点,IP,动作,RFID,AGV名称,在线,调用,清除AGV
string[] s = new string[8];
s[0] = AliceName;
s[1] = IP;
// if (Online)
// {
s[2] = EmptyShelfCnt.ToString();//string.Format("({0},{1})", position.X.ToString("f2"), position.Y.ToString("f2"));
s[3] = nodeStatus.ToString();
s[4] = ClientLevel.ToString();
s[5] = RFID;
// s[5] = AgvName;
// }
s[6] = Online ? "在线" : "离线";
s[7] = IsUse ? "是" : "否";
// s[8] = "清除";
return s;
}
/// <summary>
/// 脱机
/// </summary>
public void Offline()
{
RFID = "00";
nodeStatus = eNodeStatus.None;
AgvName = "";
Online = false;
}
public virtual Job GetNewJob(Agv_Info agv)
{
return null;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AGVControl
{
/// <summary>
/// 双层线有料料架出口
/// </summary>
public class DoubleLineNodeFor4C : ClientNode
{
public DoubleLineNodeFor4C(string name, string ip, string aliceName, string lineName, string pos_name, string pos_guid, bool isUse, int emptyCnt) : base(name, ip, aliceName, lineName, pos_name, pos_guid, isUse, emptyCnt)
{
}
/// <summary>
/// 双层线任务
/// </summary>
/// <param name="currentAgv"></param>
/// <returns></returns>
public override Job GetNewJob(Agv_Info currentAgv)
{
if (!SettingString.C4_AGV_IPs.Contains(currentAgv.IP))
return null;
if (!Common.CheckCanExecuteMission(currentAgv))
return null;
if (!Common.CheckAGVStatusNone(currentAgv))
return null;
//执行空料架任务的小车数量
int emptyJobCnt = 0;
foreach (Agv_Info agv in Common.agvInfo)
{
if (!SettingString.C4_AGV_IPs.Contains(agv.IP))
continue;
if (agv.CurJob is GoEmptyShelfLineJob || agv.CurJob is EmptyShelfBackJob)
{
emptyJobCnt++;
}
}
if ((SettingString.AGVCNT - emptyJobCnt).Equals(2))//保留2辆小车出满料架
{
return null;
}
//出工单料的目的地是否有空料架
if (Common.FindEmptyShelfBeforeSendFullShelf(out string nodeName))
{
if (nodeName.StartsWith(SettingString.C4_Name_Prefix) && SettingString.C4_AGV_IPs.Contains(currentAgv.IP))
{
ClientNode clientNode = Common.nodeInfo.Find(s => s.Name.Equals(nodeName));
int cnt = 0;
foreach (Agv_Info agv in Common.agvInfo)
{
if (agv.CurJob is GoEmptyShelfLineJob)
{
if (((GoEmptyShelfLineJob)agv.CurJob).EmptyShelfPlace.Equals(nodeName))
cnt++;
}
}
if (cnt < clientNode.EmptyShelfCnt)
{
return new GoEmptyShelfLineJob(currentAgv.Place, nodeName);
}
}
}
//回收空料架
if (Common.FindEmptyShelfNode(currentAgv, out string emptyNodeName))
{
if (SettingString.C4_AGV_IPs.Contains(currentAgv.IP))
{
int i = Common.agvInfo.FindIndex(s => s.CurJob is GoEmptyShelfLineJob && ((GoEmptyShelfLineJob)s.CurJob).EmptyShelfPlace.Equals(emptyNodeName));
if (i == -1)
return new GoEmptyShelfLineJob(currentAgv.Place, emptyNodeName);
}
}
//出满料
if (Common.FindFullShelfTask(currentAgv))
{
if (SettingString.C4_AGV_IPs.Contains(currentAgv.IP))
{
int i = Common.agvInfo.FindIndex(s => s.CurJob is GoFullShelfStationJob && !s.IP.Equals(currentAgv.IP));
if (i == -1)
return new GoFullShelfStationJob(currentAgv.Place);
}
}
return null;
}
}
}
using BLL;
using log4net.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AGVControl
{
/// <summary>
///
/// </summary>
public class DoubleLineNodeFor4D : ClientNode
{
public DoubleLineNodeFor4D(string name, string ip, string aliceName, string lineName, string pos_name, string pos_guid, bool isUse, int emptyCnt) : base(name, ip, aliceName, lineName, pos_name, pos_guid, isUse, emptyCnt)
{
}
/// <summary>
/// 双层线任务
/// </summary>
/// <param name="currentAgv"></param>
/// <returns></returns>
public override Job GetNewJob(Agv_Info currentAgv)
{
if (SettingString.C4_AGV_IPs.Contains(currentAgv.IP))
return null;
if (!Common.CheckCanExecuteMission(currentAgv))
return null;
if (!Common.CheckAGVStatusNone(currentAgv))
return null;
//执行空料架任务的小车数量
int emptyJobCnt = 0;
foreach (Agv_Info agv in Common.agvInfo)
{
if (SettingString.C4_AGV_IPs.Contains(agv.IP))
continue;
if (agv.CurJob is GoEmptyShelfLineJob || agv.CurJob is EmptyShelfBackJob)
{
emptyJobCnt++;
}
}
if ((SettingString.AGVCNT / 2 - emptyJobCnt).Equals(1))//保留1辆小车出满料架
{
return null;
}
//出工单料的目的地是否有空料架
if (Common.FindEmptyShelfBeforeSendFullShelf(out string nodeName))
{
if (nodeName.StartsWith(SettingString.D4_Name_Prefix) && !SettingString.C4_AGV_IPs.Contains(currentAgv.IP))
{
ClientNode clientNode = Common.nodeInfo.Find(s => s.Name.Equals(nodeName));
int cnt = 0;
foreach (Agv_Info agv in Common.agvInfo)
{
if (SettingString.C4_AGV_IPs.Contains(agv.IP))
continue;
if (agv.CurJob is GoEmptyShelfLineJob)
{
if (((GoEmptyShelfLineJob)agv.CurJob).EmptyShelfPlace.Equals(nodeName))
cnt++;
}
}
if (cnt < clientNode.EmptyShelfCnt)
{
return new GoEmptyShelfLineJob(currentAgv.Place, nodeName);
}
}
}
//回收空料架
if (Common.FindEmptyShelfNode(currentAgv, out string emptyNodeName))
{
if (!SettingString.C4_AGV_IPs.Contains(currentAgv.IP))
{
int i = Common.agvInfo.FindIndex(s => s.CurJob is GoEmptyShelfLineJob && ((GoEmptyShelfLineJob)s.CurJob).EmptyShelfPlace.Equals(emptyNodeName));
if (i == -1)
return new GoEmptyShelfLineJob(currentAgv.Place, emptyNodeName);
}
}
//出满料
if (Common.FindFullShelfTask(currentAgv))
{
if (!SettingString.C4_AGV_IPs.Contains(currentAgv.IP))
{
int i = Common.agvInfo.FindIndex(s => s.CurJob is GoFullShelfStationJob && !s.IP.Equals(currentAgv.IP));
if (i > -1)
{
return null;
}
ClientNode node = Common.nodeInfo.Find(s => s.Name.Equals(SettingString.A6)
&& (s.StateEquals(eNodeStatus.NeedLeave) || s.StateEquals(eNodeStatus.NeedEnterLeave)) && !s.RFID.Equals("00"));
if (node != null && node.Name.Equals(SettingString.A6))
{
if (AGVManager.FindFullShelfTarget(node.RFID, out AGVManager.BoxDestInfo boxDestInfo))
{
if (boxDestInfo != null)
{
i = Common.agvInfo.FindIndex(s => s.CurJob is SendFullShelfToLineJob && !s.IP.Equals(currentAgv.IP)
&& ((SendFullShelfToLineJob)s.CurJob).FullShelfPlace.Equals(boxDestInfo.location));
if (i > -1)
return null;
}
}
}
return new GoFullShelfStationJob(currentAgv.Place);
}
}
return null;
}
}
}
此文件类型无法预览
此文件类型无法预览
文件属性发生变化
此文件类型无法预览
此文件类型无法预览
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="RestSharp" version="106.11.4" targetFramework="net461" />
</packages>
\ No newline at end of file \ No newline at end of file
此文件类型无法预览
using Microsoft.Win32.SafeHandles;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace AsaPL
{
/// <summary>
/// AGV客户端,对接双层线、生产线
/// </summary>
public class AgvClient
{
private bool _loop;
private Socket _client; //客户端
private List<ClientNode> _node;
private int countRecon; //重连次数
private Thread tSend; //发送线程
private Thread tListen; //监听网络线程
private Thread tRecon; //重连线程
private readonly log4net.ILog LOG;
private readonly string IP; //远程IP地址
private const int PORT = 9501; //端口
private const int SEND_INTERVAL = 2000; //客户端发送所有节点后的间隔
/// <summary>
/// 小车动作事件
/// </summary>
public delegate void ActionEvent(string name);
/// <summary>
/// 小车已准备好,料架准备进入流水线
/// </summary>
public event ActionEvent ReadyEnter;
/// <summary>
/// 小车已准备好,料架准备流出流水线
/// </summary>
public event ActionEvent ReadyLeave;
public event ActionEvent AGVFinishEnter;
public event ActionEvent AGVFinishLeave;
/// <summary>
/// AGV客户端,对接双层线、生产线
/// </summary>
/// <param name="serverIP">服务器IP地址</param>
/// <param name="logName"></param>
public AgvClient(string serverIP, string logName = "AgvClient")
{
IP = serverIP;
_node = new List<ClientNode>();
LOG = log4net.LogManager.GetLogger(logName);
}
/// <summary>
/// 是否连接服务器
/// </summary>
public bool IsConn { private set; get; } = false;
/// <summary>
/// 取消状态,true发送none,false发送实际状态
/// </summary>
public bool CancelState { set; get; } = false;
/// <summary>
/// 连接
/// </summary>
public void Connect()
{
countRecon = 0;
_loop = true;
IsConn = false;
tRecon = new Thread(new ThreadStart(Reconnect));
tListen = new Thread(new ThreadStart(ListenNet));
tSend = new Thread(new ThreadStart(SendStatus));
tRecon.Start();
tListen.Start();
tSend.Start();
LOG.Info("Connect");
}
/// <summary>
/// 关闭
/// </summary>
public void Close()
{
_loop = false;
IsConn = false;
if (_client != null)
{
_client.Close();
_client = null;
}
LOG.Info("Close");
}
/// <summary>
/// 设置状态
/// </summary>
/// <param name="name">节点名称</param>
/// <param name="rfid">RFID</param>
/// <param name="action"></param>
/// <param name="level"></param>
public void SetStatus(string name, string rfid = "", ClientAction action = ClientAction.None, ClientLevel level = ClientLevel.Low)
{
int idx = _node.FindIndex(s => s.Name.Equals(name));
if (idx == -1)
{
ClientNode node = new ClientNode(name, rfid, action, level);
_node.Add(node);
idx = _node.Count - 1;
}
else
{
_node[idx].RFID = rfid;
_node[idx].Action = action;
_node[idx].Level = level;
}
LOG.Info("SetStatus " + _node[idx].ToText());
}
/// <summary>
/// 允许进入
/// </summary>
/// <param name="name"></param>
public void MayEnter(string name)
{
LOG.Info(name + " MayEnter");
ClientNode node = new ClientNode(name, "", ClientAction.MayEnter, ClientLevel.High);
byte[] buff = Encode(node);
bool bln = Send(buff);
}
/// <summary>
/// 允许离开
/// </summary>
/// <param name="name"></param>
public void MayLeave(string name)
{
LOG.Info(name + " MayLeave");
ClientNode node = new ClientNode(name, "", ClientAction.MayLeave, ClientLevel.High);
byte[] buff = Encode(node);
bool bln = Send(buff);
}
/// <summary>
/// 完成进入
/// </summary>
/// <param name="name"></param>
public void FinishEnter(string name)
{
LOG.Info(name + " FinishEnter");
ClientNode node = new ClientNode(name, "", ClientAction.FinishEnter, ClientLevel.High);
byte[] buff = Encode(node);
bool bln = Send(buff);
}
/// <summary>
/// 完成离开
/// </summary>
/// <param name="name"></param>
public void FinishLeave(string name)
{
LOG.Info(name + " FinishLeave");
ClientNode node = new ClientNode(name, "", ClientAction.FinishLeave, ClientLevel.High);
byte[] buff = Encode(node);
bool bln = Send(buff);
}
/// <summary>
/// 重连线程
/// </summary>
private void Reconnect()
{
while (_loop)
{
if (!IsConn)
{
Open();
if (IsConn)
{
countRecon = 0;
LOG.Info("Server connection successful");
}
else
{
LOG.Info("Server connection failed " + ++countRecon + " times");
}
}
Thread.Sleep(1000);
}
}
/// <summary>
/// 打开,连接到服务器
/// </summary>
private void Open()
{
try
{
LOG.Info("Connect " + IP + ":" + PORT);
if (CheckIP(IP))
{
_client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 2000);
_client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 2000);
_client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, 1);
_client.Connect(IPAddress.Parse(IP), PORT);
if (!_loop) return;
IsConn = true;
LOG.Info("Connect OK");
}
}
catch (Exception ex)
{
IsConn = false;
LOG.Error("Open()", ex);
}
}
/// <summary>
/// 监听线程
/// </summary>
private void ListenNet()
{
byte[] temp = new byte[200];
while (_loop)
{
Thread.Sleep(100);
if (!IsConn) continue;
if (_client == null) continue;
try
{
if (_client.Available > 0)
{
int count = _client.Receive(temp);
byte[] _buffer = new byte[count];
Array.Copy(temp, 0, _buffer, 0, count);
ClientNode node = Decode(_buffer);
if (node == null)
{
LOG.Info("Command decoding failed: " + HexBuff(_buffer));
}
else
{
LOG.Info("From server: " + node.ToText());
Resolve(node);
}
}
}
catch (Exception ex)
{
IsConn = false;
LOG.Error("ListenNet()", ex);
}
}
}
/// <summary>
/// 分析数据包
/// </summary>
/// <param name="result"></param>
private void Resolve(ClientNode result)
{
try
{
if (result.Action == ClientAction.ReadyEnter)
{
LOG.Info("Trigger ReadyEnter Event");
ReadyEnter?.Invoke(result.Name);
}
else if (result.Action == ClientAction.ReadyLeave)
{
LOG.Info("Trigger ReadyLeave Event");
ReadyLeave?.Invoke(result.Name);
}
else if(result.Action == ClientAction.FinishEnter)
{
LOG.Info("Trigger FinishEnter Event");
AGVFinishEnter?.Invoke(result.Name);
}
else if(result.Action == ClientAction.FinishLeave)
{
LOG.Info("Trigger FinishLeave Event");
AGVFinishLeave.Invoke(result.Name);
}
}
catch (Exception ex)
{
LOG.Error("Resolve()", ex);
}
}
/// <summary>
/// 连续发送状态线程
/// </summary>
private void SendStatus()
{
while (_loop)
{
if (!IsConn) continue;
Thread.Sleep(SEND_INTERVAL);
if (!IsConn) continue;
for (int i = 0; i < _node.Count; i++)
{
if (!_loop) break;
Thread.Sleep(100);
byte[] buff = Encode(_node[i]);
bool bln = Send(buff);
if (!bln)
{
IsConn = false;
break;
}
}
}
}
/// <summary>
/// 发送命令
/// </summary>
/// <param name="buff"></param>
/// <returns></returns>
private bool Send(byte[] buff)
{
if (!IsConn)
{
LOG.Info("服务器没有连接");
return false;
}
try
{
_client.Send(buff);
LOG.Debug("Send: " + HexBuff(buff));
return true;
}
catch (Exception ex)
{
LOG.Error("Send()", ex);
IsConn = false;
return false;
}
}
/// <summary>
/// 编码
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
private byte[] Encode(ClientNode node)
{
int idx = 0;
byte[] buff = new byte[12];
buff[idx++] = 0xAD;
buff[idx++] = (byte)node.Name[0];
buff[idx++] = Convert.ToByte(node.Name.Substring(1));
buff[idx++] = (byte)node.RFID[0];
buff[idx++] = Convert.ToByte(node.RFID.Substring(1));
if (CancelState)
buff[idx++] = (byte)ClientAction.None;
else
buff[idx++] = (byte)node.Action;
buff[idx++] = (byte)node.Level;
idx += 4; //预留
buff[idx] = 0xDA;
return buff;
}
/// <summary>
/// 解码
/// </summary>
/// <param name="buff"></param>
/// <returns></returns>
private ClientNode Decode(byte[] buff)
{
int idx = 0;
if (buff[idx++] != 0xAD) return null;
string name = (char)buff[idx] + buff[idx + 1].ToString();
idx += 2;
string rfid = (char)buff[idx] + buff[idx + 1].ToString();
idx += 2;
ClientAction action = (ClientAction)buff[idx++];
ClientLevel level = (ClientLevel)buff[idx++];
idx += 4; //预留
if (buff[idx] != 0xDA) return null;
ClientNode node = new ClientNode(name, rfid, action, level);
return node;
}
/// <summary>
/// 16进制
/// </summary>
/// <param name="buff"></param>
/// <returns></returns>
private string HexBuff(byte[] buff)
{
string s = "";
if (buff == null) return s;
for (int i = 0; i < buff.Length; i++)
s += buff[i].ToString("X2") + " ";
return s;
}
/// <summary>
/// 检查IP地址
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
private bool CheckIP(string ip)
{
//IP合法
string pattern = @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$";
bool rtn = System.Text.RegularExpressions.Regex.IsMatch(ip, pattern);
if (!rtn)
{
LOG.Info("Illegal IP address " + ip);
return false;
}
//Ping服务端
try
{
System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
System.Net.NetworkInformation.PingReply result = ping.Send(ip, 2000);
ping.Dispose();
if (result.Status != System.Net.NetworkInformation.IPStatus.Success)
{
LOG.Info("Ping " + ip + " request timeout");
return false;
}
return true;
}
catch (Exception ex)
{
LOG.Error("CheckIP()", ex);
return false;
}
}
}
/// <summary>
/// 客户端的节点
/// </summary>
public class ClientNode
{
private string rfid = "00";
/// <summary>
/// 节点名称
/// </summary>
public string Name { set; get; }
/// <summary>
/// RFID
/// </summary>
public string RFID
{
set
{
if (value.Length < 2)
rfid = value.PadLeft(2, '0');
else
rfid = value;
}
get
{
return rfid;
}
}
/// <summary>
/// 动作
/// </summary>
public ClientAction Action { set; get; }
/// <summary>
/// 优先级
/// </summary>
public ClientLevel Level { set; get; }
/// <summary>
/// 客户端节点
/// </summary>
/// <param name="name"></param>
/// <param name="rfid"></param>
/// <param name="action"></param>
/// <param name="level"></param>
public ClientNode(string name, string rfid, ClientAction action, ClientLevel level)
{
Name = name;
RFID = rfid;
Action = action;
Level = level;
}
/// <summary>
/// 所有属性的文本形式
/// </summary>
/// <returns></returns>
public string ToText()
{
string s = string.Format("Name={0}, Action={1}, Level={2}", Name, Action, Level);
return s;
}
}
/// <summary>
/// 客户端的动作
/// </summary>
public enum ClientAction : byte
{
/// <summary>
/// 没有动作
/// </summary>
None = 0,
/// <summary>
/// 需要7寸D料架
/// </summary>
NeedD = 1,
/// <summary>
/// 需要大尺寸C料架
/// </summary>
NeedC = 2,
/// <summary>
/// 需要进入料架
/// </summary>
NeedEnter = 3,
/// <summary>
/// 需要出去料架
/// </summary>
NeedLeave = 4,
/// <summary>
/// 需要进入离开料架
/// </summary>
NeedEnterLeave = 5,
/// <summary>
/// 准备进入,服务器发送
/// </summary>
ReadyEnter = 6,
/// <summary>
/// 可以进入料架
/// </summary>
MayEnter = 7,
/// <summary>
/// 完成进入料架
/// </summary>
FinishEnter = 8,
/// <summary>
/// 准备离开,服务器发送
/// </summary>
ReadyLeave = 9,
/// <summary>
/// 可以出去料架
/// </summary>
MayLeave = 10,
/// <summary>
/// 完成出去料架
/// </summary>
FinishLeave = 11,
}
/// <summary>
/// 客户端的优先级
/// </summary>
public enum ClientLevel : byte
{
/// <summary>
/// 低
/// </summary>
Low = 0,
/// <summary>
/// 中等
/// </summary>
Middle = 1,
/// <summary>
/// 高
/// </summary>
High = 2
}
}
<?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>{D9154766-67B0-4082-AF8B-DCC7C4CFB5A2}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>AgvClient</RootNamespace>
<AssemblyName>AsaPL.AgvClient</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<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="log4net">
<HintPath>..\..\..\DLL\log4net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AgvClient.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file \ No newline at end of file
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("AgvClient")]
[assembly: AssemblyDescription("AGV对接双层线生产线客户端")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("挚锦科技")]
[assembly: AssemblyProduct("AgvClient")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("d9154766-67b0-4082-af8b-dcc7c4cfb5a2")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.1")]
[assembly: AssemblyFileVersion("1.0.0.1")]
文件属性发生变化
文件属性发生变化
<?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>{E1C0827A-FA12-49A9-AC71-6D3E6518754A}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>AgvClientTest</RootNamespace>
<AssemblyName>AgvClientTest</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<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' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="AsaPL.AgvClient, Version=1.0.0.1, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\AgvClient\bin\Debug\AsaPL.AgvClient.dll</HintPath>
</Reference>
<Reference Include="log4net">
<HintPath>..\..\..\DLL\log4net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Form1.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file \ No newline at end of file
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<log4net>
<appender name="AgvClient" type="log4net.Appender.RollingFileAppender">
<file value="logs/AgvClient.log"/>
<param name="Encoding" value="UTF-8"/>
<appendToFile value="true"/>
<rollingStyle value="Date"/>
<datePattern value="yyyy-MM-dd"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="[%date][%t]%-5p %m%n"/>
</layout>
</appender>
<root>
<level value="Info"/>
<appender-ref ref="AgvClient"/>
</root>
</log4net>
</configuration>
\ No newline at end of file \ No newline at end of file
namespace AgvClientTest
{
partial class Form1
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.comboBox1 = new System.Windows.Forms.ComboBox();
this.comboBox2 = new System.Windows.Forms.ComboBox();
this.textBox1 = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.button3 = new System.Windows.Forms.Button();
this.button4 = new System.Windows.Forms.Button();
this.button6 = new System.Windows.Forms.Button();
this.button7 = new System.Windows.Forms.Button();
this.button8 = new System.Windows.Forms.Button();
this.button9 = new System.Windows.Forms.Button();
this.button10 = new System.Windows.Forms.Button();
this.button11 = new System.Windows.Forms.Button();
this.button12 = new System.Windows.Forms.Button();
this.button13 = new System.Windows.Forms.Button();
this.button14 = new System.Windows.Forms.Button();
this.button15 = new System.Windows.Forms.Button();
this.button16 = new System.Windows.Forms.Button();
this.button17 = new System.Windows.Forms.Button();
this.button19 = new System.Windows.Forms.Button();
this.button20 = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.button18 = new System.Windows.Forms.Button();
this.button5 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.checkBox1 = new System.Windows.Forms.CheckBox();
this.label5 = new System.Windows.Forms.Label();
this.comboBox3 = new System.Windows.Forms.ComboBox();
this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
// button1
//
this.button1.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.button1.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button1.Location = new System.Drawing.Point(455, 49);
this.button1.Margin = new System.Windows.Forms.Padding(4);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(115, 37);
this.button1.TabIndex = 0;
this.button1.Text = "设置";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// comboBox1
//
this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBox1.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.comboBox1.FormattingEnabled = true;
this.comboBox1.Location = new System.Drawing.Point(285, 54);
this.comboBox1.Margin = new System.Windows.Forms.Padding(4);
this.comboBox1.Name = "comboBox1";
this.comboBox1.Size = new System.Drawing.Size(153, 32);
this.comboBox1.TabIndex = 2;
//
// comboBox2
//
this.comboBox2.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBox2.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.comboBox2.FormattingEnabled = true;
this.comboBox2.Items.AddRange(new object[] {
"A5",
"A6",
"E1",
"E2",
"E3",
"E4",
"E5",
"E6",
"E8",
"E9",
"E10",
"E11",
"E12",
"E14",
"E15",
"E16",
"E21",
"E22",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8",
"G9",
"G10",
"G11",
"G12",
"G13",
"G14",
"G15",
"G16"});
this.comboBox2.Location = new System.Drawing.Point(81, 54);
this.comboBox2.Margin = new System.Windows.Forms.Padding(4);
this.comboBox2.Name = "comboBox2";
this.comboBox2.Size = new System.Drawing.Size(153, 32);
this.comboBox2.TabIndex = 3;
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(105, 22);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(100, 25);
this.textBox1.TabIndex = 4;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(17, 25);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(71, 15);
this.label1.TabIndex = 5;
this.label1.Text = "A6_RFID:";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(8, 65);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(37, 15);
this.label2.TabIndex = 6;
this.label2.Text = "节点";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(241, 71);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(37, 15);
this.label3.TabIndex = 7;
this.label3.Text = "状态";
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(239, 22);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(55, 15);
this.label4.TabIndex = 8;
this.label4.Text = "label4";
//
// button3
//
this.button3.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button3.Location = new System.Drawing.Point(372, 108);
this.button3.Margin = new System.Windows.Forms.Padding(4);
this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(63, 47);
this.button3.TabIndex = 10;
this.button3.Text = "E6";
this.button3.UseVisualStyleBackColor = true;
this.button3.Click += new System.EventHandler(this.SetLineState);
//
// button4
//
this.button4.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button4.Location = new System.Drawing.Point(84, 108);
this.button4.Margin = new System.Windows.Forms.Padding(4);
this.button4.Name = "button4";
this.button4.Size = new System.Drawing.Size(63, 47);
this.button4.TabIndex = 11;
this.button4.Text = "E2";
this.button4.UseVisualStyleBackColor = true;
this.button4.Click += new System.EventHandler(this.SetLineState);
//
// button6
//
this.button6.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button6.Location = new System.Drawing.Point(443, 47);
this.button6.Margin = new System.Windows.Forms.Padding(4);
this.button6.Name = "button6";
this.button6.Size = new System.Drawing.Size(63, 47);
this.button6.TabIndex = 13;
this.button6.Text = "G10";
this.button6.UseVisualStyleBackColor = true;
this.button6.Click += new System.EventHandler(this.SetLineState);
//
// button7
//
this.button7.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button7.Location = new System.Drawing.Point(585, 108);
this.button7.Margin = new System.Windows.Forms.Padding(4);
this.button7.Name = "button7";
this.button7.Size = new System.Drawing.Size(63, 47);
this.button7.TabIndex = 14;
this.button7.Text = "E9";
this.button7.UseVisualStyleBackColor = true;
this.button7.Click += new System.EventHandler(this.SetLineState);
//
// button8
//
this.button8.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button8.Location = new System.Drawing.Point(301, 108);
this.button8.Margin = new System.Windows.Forms.Padding(4);
this.button8.Name = "button8";
this.button8.Size = new System.Drawing.Size(63, 47);
this.button8.TabIndex = 15;
this.button8.Text = "E5";
this.button8.UseVisualStyleBackColor = true;
this.button8.Click += new System.EventHandler(this.SetLineState);
//
// button9
//
this.button9.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.button9.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button9.Location = new System.Drawing.Point(13, 108);
this.button9.Margin = new System.Windows.Forms.Padding(4);
this.button9.Name = "button9";
this.button9.Size = new System.Drawing.Size(63, 47);
this.button9.TabIndex = 16;
this.button9.Text = "E1";
this.button9.UseVisualStyleBackColor = true;
this.button9.Click += new System.EventHandler(this.SetLineState);
//
// button10
//
this.button10.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button10.Location = new System.Drawing.Point(13, 163);
this.button10.Margin = new System.Windows.Forms.Padding(4);
this.button10.Name = "button10";
this.button10.Size = new System.Drawing.Size(63, 47);
this.button10.TabIndex = 17;
this.button10.Text = "E10";
this.button10.UseVisualStyleBackColor = true;
this.button10.Click += new System.EventHandler(this.SetLineState);
//
// button11
//
this.button11.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button11.Location = new System.Drawing.Point(301, 163);
this.button11.Margin = new System.Windows.Forms.Padding(4);
this.button11.Name = "button11";
this.button11.Size = new System.Drawing.Size(63, 47);
this.button11.TabIndex = 18;
this.button11.Text = "E14";
this.button11.UseVisualStyleBackColor = true;
this.button11.Click += new System.EventHandler(this.SetLineState);
//
// button12
//
this.button12.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button12.Location = new System.Drawing.Point(443, 163);
this.button12.Margin = new System.Windows.Forms.Padding(4);
this.button12.Name = "button12";
this.button12.Size = new System.Drawing.Size(63, 47);
this.button12.TabIndex = 28;
this.button12.Text = "E16";
this.button12.UseVisualStyleBackColor = true;
this.button12.Click += new System.EventHandler(this.SetLineState);
//
// button13
//
this.button13.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button13.Location = new System.Drawing.Point(155, 163);
this.button13.Margin = new System.Windows.Forms.Padding(4);
this.button13.Name = "button13";
this.button13.Size = new System.Drawing.Size(63, 47);
this.button13.TabIndex = 27;
this.button13.Text = "E12";
this.button13.UseVisualStyleBackColor = true;
this.button13.Click += new System.EventHandler(this.SetLineState);
//
// button14
//
this.button14.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button14.Location = new System.Drawing.Point(159, 108);
this.button14.Margin = new System.Windows.Forms.Padding(4);
this.button14.Name = "button14";
this.button14.Size = new System.Drawing.Size(63, 47);
this.button14.TabIndex = 26;
this.button14.Text = "E3";
this.button14.UseVisualStyleBackColor = true;
this.button14.Click += new System.EventHandler(this.SetLineState);
//
// button15
//
this.button15.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button15.Location = new System.Drawing.Point(514, 47);
this.button15.Margin = new System.Windows.Forms.Padding(4);
this.button15.Name = "button15";
this.button15.Size = new System.Drawing.Size(63, 47);
this.button15.TabIndex = 25;
this.button15.Text = "G21";
this.button15.UseVisualStyleBackColor = true;
this.button15.Click += new System.EventHandler(this.SetLineState);
//
// button16
//
this.button16.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button16.Location = new System.Drawing.Point(84, 163);
this.button16.Margin = new System.Windows.Forms.Padding(4);
this.button16.Name = "button16";
this.button16.Size = new System.Drawing.Size(63, 47);
this.button16.TabIndex = 24;
this.button16.Text = "E11";
this.button16.UseVisualStyleBackColor = true;
this.button16.Click += new System.EventHandler(this.SetLineState);
//
// button17
//
this.button17.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button17.Location = new System.Drawing.Point(372, 163);
this.button17.Margin = new System.Windows.Forms.Padding(4);
this.button17.Name = "button17";
this.button17.Size = new System.Drawing.Size(63, 47);
this.button17.TabIndex = 23;
this.button17.Text = "E15";
this.button17.UseVisualStyleBackColor = true;
this.button17.Click += new System.EventHandler(this.SetLineState);
//
// button19
//
this.button19.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button19.Location = new System.Drawing.Point(230, 108);
this.button19.Margin = new System.Windows.Forms.Padding(4);
this.button19.Name = "button19";
this.button19.Size = new System.Drawing.Size(63, 47);
this.button19.TabIndex = 21;
this.button19.Text = "E4";
this.button19.UseVisualStyleBackColor = true;
this.button19.Click += new System.EventHandler(this.SetLineState);
//
// button20
//
this.button20.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button20.Location = new System.Drawing.Point(514, 108);
this.button20.Margin = new System.Windows.Forms.Padding(4);
this.button20.Name = "button20";
this.button20.Size = new System.Drawing.Size(63, 47);
this.button20.TabIndex = 20;
this.button20.Text = "E8";
this.button20.UseVisualStyleBackColor = true;
this.button20.Click += new System.EventHandler(this.SetLineState);
//
// groupBox1
//
this.groupBox1.Controls.Add(this.button18);
this.groupBox1.Controls.Add(this.button5);
this.groupBox1.Controls.Add(this.button2);
this.groupBox1.Controls.Add(this.checkBox1);
this.groupBox1.Controls.Add(this.label5);
this.groupBox1.Controls.Add(this.comboBox3);
this.groupBox1.Controls.Add(this.button8);
this.groupBox1.Controls.Add(this.button12);
this.groupBox1.Controls.Add(this.button3);
this.groupBox1.Controls.Add(this.button13);
this.groupBox1.Controls.Add(this.button4);
this.groupBox1.Controls.Add(this.button14);
this.groupBox1.Controls.Add(this.button6);
this.groupBox1.Controls.Add(this.button15);
this.groupBox1.Controls.Add(this.button7);
this.groupBox1.Controls.Add(this.button16);
this.groupBox1.Controls.Add(this.button9);
this.groupBox1.Controls.Add(this.button17);
this.groupBox1.Controls.Add(this.button10);
this.groupBox1.Controls.Add(this.button19);
this.groupBox1.Controls.Add(this.button11);
this.groupBox1.Controls.Add(this.button20);
this.groupBox1.Location = new System.Drawing.Point(11, 109);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(692, 260);
this.groupBox1.TabIndex = 29;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "产线";
//
// button18
//
this.button18.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button18.Location = new System.Drawing.Point(585, 47);
this.button18.Margin = new System.Windows.Forms.Padding(4);
this.button18.Name = "button18";
this.button18.Size = new System.Drawing.Size(63, 47);
this.button18.TabIndex = 34;
this.button18.Text = "G22";
this.button18.UseVisualStyleBackColor = true;
this.button18.Click += new System.EventHandler(this.SetLineState);
//
// button5
//
this.button5.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button5.Location = new System.Drawing.Point(585, 163);
this.button5.Margin = new System.Windows.Forms.Padding(4);
this.button5.Name = "button5";
this.button5.Size = new System.Drawing.Size(63, 47);
this.button5.TabIndex = 33;
this.button5.Text = "E22";
this.button5.UseVisualStyleBackColor = true;
this.button5.Click += new System.EventHandler(this.SetLineState);
//
// button2
//
this.button2.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.button2.Location = new System.Drawing.Point(514, 163);
this.button2.Margin = new System.Windows.Forms.Padding(4);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(63, 47);
this.button2.TabIndex = 32;
this.button2.Text = "E21";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.SetLineState);
//
// checkBox1
//
this.checkBox1.AutoSize = true;
this.checkBox1.Checked = true;
this.checkBox1.CheckState = System.Windows.Forms.CheckState.Checked;
this.checkBox1.Location = new System.Drawing.Point(13, 24);
this.checkBox1.Name = "checkBox1";
this.checkBox1.Size = new System.Drawing.Size(89, 19);
this.checkBox1.TabIndex = 31;
this.checkBox1.Text = "自动回复";
this.checkBox1.UseVisualStyleBackColor = true;
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(206, 24);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(55, 15);
this.label5.TabIndex = 30;
this.label5.Text = "label5";
//
// comboBox3
//
this.comboBox3.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBox3.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.comboBox3.FormattingEnabled = true;
this.comboBox3.Location = new System.Drawing.Point(8, 62);
this.comboBox3.Margin = new System.Windows.Forms.Padding(4);
this.comboBox3.Name = "comboBox3";
this.comboBox3.Size = new System.Drawing.Size(166, 32);
this.comboBox3.TabIndex = 29;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(723, 388);
this.ControlBox = false;
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.label4);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.comboBox2);
this.Controls.Add(this.comboBox1);
this.Controls.Add(this.button1);
this.Margin = new System.Windows.Forms.Padding(4);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "Form1";
this.ShowIcon = false;
this.Text = "agv对接模拟客户端";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
this.Load += new System.EventHandler(this.Form1_Load);
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button button1;
private System.Windows.Forms.ComboBox comboBox1;
private System.Windows.Forms.ComboBox comboBox2;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.Button button4;
private System.Windows.Forms.Button button6;
private System.Windows.Forms.Button button7;
private System.Windows.Forms.Button button8;
private System.Windows.Forms.Button button9;
private System.Windows.Forms.Button button10;
private System.Windows.Forms.Button button11;
private System.Windows.Forms.Button button12;
private System.Windows.Forms.Button button13;
private System.Windows.Forms.Button button14;
private System.Windows.Forms.Button button15;
private System.Windows.Forms.Button button16;
private System.Windows.Forms.Button button17;
private System.Windows.Forms.Button button19;
private System.Windows.Forms.Button button20;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.ComboBox comboBox3;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.CheckBox checkBox1;
private System.Windows.Forms.Button button5;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button18;
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AgvClientTest
{
public partial class Form1 : Form
{
private AsaPL.AgvClient client;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 12; i++)
comboBox1.Items.Add((AsaPL.ClientAction)i);
comboBox1.SelectedIndex = 0;
comboBox2.SelectedIndex = 0;
comboBox3.Items.Add(AsaPL.ClientAction.MayEnter);
comboBox3.Items.Add(AsaPL.ClientAction.MayLeave);
comboBox3.SelectedIndex = 0;
client = new AsaPL.AgvClient("10.85.199.1");
client.ReadyEnter += AGV_ReadyEnter;
client.ReadyLeave += AGV_ReadyLeave;
//client.SetStatus("E1", "", AsaPL.ClientAction.None);
//client.SetStatus("E2", "", AsaPL.ClientAction.None);
//client.SetStatus("E3", "", AsaPL.ClientAction.None);
//client.SetStatus("E4", "", AsaPL.ClientAction.None);
//client.SetStatus("E5", "", AsaPL.ClientAction.None);
//client.SetStatus("E6", "", AsaPL.ClientAction.None);
//client.SetStatus("E8", "", AsaPL.ClientAction.None);
//client.SetStatus("E9", "", AsaPL.ClientAction.None);
//client.SetStatus("E10", "", AsaPL.ClientAction.None);
//client.SetStatus("E11", "", AsaPL.ClientAction.None);
//client.SetStatus("E12", "", AsaPL.ClientAction.None);
//client.SetStatus("E14", "", AsaPL.ClientAction.None);
//client.SetStatus("E15", "", AsaPL.ClientAction.None);
//client.SetStatus("E16", "", AsaPL.ClientAction.None);
//client.SetStatus("D4FeederIn", "", AsaPL.ClientAction.None);
//client.SetStatus("D4FeederOut", "", AsaPL.ClientAction.None);
//client.SetStatus("C4FeederIn", "", AsaPL.ClientAction.None);
//client.SetStatus("C4FeederOut", "", AsaPL.ClientAction.None);
client.Connect();
}
private void AGV_ReadyEnter(string nodeName)
{
if (checkBox1.Checked)
{
if (nodeName.StartsWith("A") || nodeName.EndsWith("A"))//|| nodeName.Equals("G10") || nodeName.Equals("G7")
return;
label4.Text = "收到" + nodeName + "ReadyEnter,节点状态变为MayEnter";
client.SetStatus(nodeName, "", AsaPL.ClientAction.MayEnter);
System.Threading.Thread.Sleep(10000);
client.SetStatus(nodeName, "", AsaPL.ClientAction.None);
label4.Text = "设置" + nodeName + " None";
}
}
private void AGV_ReadyLeave(string nodeName)
{
if (checkBox1.Checked)
{
if (nodeName.StartsWith("A") || nodeName.EndsWith("A"))//|| nodeName.Equals("G10") || nodeName.Equals("G7")
return;
label4.Text = "收到" + nodeName + "ReadyLeave,节点状态变为MayLeave";
client.SetStatus(nodeName, "", AsaPL.ClientAction.MayLeave);
System.Threading.Thread.Sleep(10000);
client.SetStatus(nodeName, "", AsaPL.ClientAction.None);
label4.Text = "设置" + nodeName + " None";
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
client.Close();
}
private void button1_Click(object sender, EventArgs e)
{
Task task = new Task(new Action(() => {
client.SetStatus(comboBox2.SelectedItem.ToString(), textBox1.Text, (AsaPL.ClientAction)comboBox1.SelectedIndex);
System.Threading.Thread.Sleep(10000);
client.SetStatus(comboBox2.SelectedItem.ToString(), "", AsaPL.ClientAction.None);
label4.Text = "设置" + comboBox2.SelectedItem.ToString() + " None";
}));
task.Start();
}
private void SetLineState(object sender, EventArgs e)
{
Task task = new Task(new Action(()=>{
if (comboBox3.SelectedItem == null)
return;
string name = ((Button)sender).Text;
client.SetStatus(name, "", (AsaPL.ClientAction)Enum.Parse(typeof(AsaPL.ClientAction), comboBox3.SelectedItem.ToString()));
label5.Text = name + " " + comboBox3.SelectedItem.ToString();
System.Threading.Thread.Sleep(10000);
client.SetStatus(name, "", AsaPL.ClientAction.None);
label5.Text = "设置" + name + " None";
}));
task.Start();
}
}
}
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
\ No newline at end of file \ No newline at end of file
using log4net.Config;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AgvClientTest
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
XmlConfigurator.Configure();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("AgvClientTest")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AgvClientTest")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("e1c0827a-fa12-49a9-ac71-6d3e6518754a")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本: 4.0.30319.42000
//
// 对此文件的更改可能导致不正确的行为,如果
// 重新生成代码,则所做更改将丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace AgvClientTest.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("AgvClientTest.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;
}
}
}
}
<?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>
\ No newline at end of file \ No newline at end of file
//------------------------------------------------------------------------------
// <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 AgvClientTest.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;
}
}
}
}
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>
文件属性发生变化
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
</appSettings>
<system.web>
<compilation debug="true"/>
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<protocolMapping>
<add scheme="https" binding="basicHttpsBinding" />
</protocolMapping>
<bindings>
<webHttpBinding>
<binding name="webBinding" maxReceivedMessageSize="2147483647" crossDomainScriptAccessEnabled="true" >
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="LineWebService.ClsWebService" behaviorConfiguration="RESTBehavior">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:11111/BenQMIR/Webservice/AGVService.asmx" />
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address =""
binding="webHttpBinding"
contract="LineWebService.IWebService"
behaviorConfiguration="ESEndPointBehavior">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<!-- Metadata Endpoints -->
<!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
<!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="RESTBehavior">
<!-- To avoid disclosing metadata information,
set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="True"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="ESEndPointBehavior">
<webHttp helpEnabled="true" />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
</configuration>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace LineWebService
{
// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的类名“Service1”。
//[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Reentrant)]
///[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class ClsWebService : IWebService
{
//private readonly log4net.ILog LOG = log4net.LogManager.GetLogger("ClsWebService");
public ClsWebService()
{
}
public Result CreateEmptyRecycleTask(string line)
{
//LOG.Info("CreateEmptyRecycleTask emptyStation=" + line);
Result res;
if (!line.Equals(""))
{
res = new Result() { Succeed = "true", ResultData = "", ErrorMessage = "" };
//IWebService_Callback callback = OperationContext.Current.GetCallbackChannel<IWebService_Callback>();
//callback.GetEmptyRecycleTask(line);
}
else
{
res = new Result() { Succeed = "false", ResultData = "", ErrorMessage = "Not find " + line };
}
//if (AGVControl.Common.agvProductionLine.TryGetValue(line, out string value))
//{
// res = new Result() { Succeed = "true", ResultData = "", ErrorMessage = "" };
//LOG.Info("WebService Response OK");
// //加到任务
// //int idx = AGVControl.Common.nodeInfo.FindIndex(s => s.Name == value);
// //if (idx > -1)
// // AGVControl.Common.linePlace.Add(value);
// //else
// // AGVControl.Common.log.Error("CreateEmptyRecycleTask " + value + "不存在");
// if (!Common.AddLinePlace(value))
// Common.log.Error("CreateEmptyRecycleTask 节点【" + value + "】不存在");
// else
// {
// Common.LogInfo("任务:" + value + " 出空料架 【" + line + "】");
// }
// //System.IO.File.WriteAllLines(Common.CONFIG_PATH + "LinePlace.txt", Common.linePlace);
//}
//else
//{
// res = new Result() { Succeed = "false", ResultData = "", ErrorMessage = "Not find " + line };
//LOG.Info("WebService Response false");
//}
return res;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace LineWebService
{
// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。
[ServiceContract]//(CallbackContract = typeof(IWebService_Callback))
public interface IWebService
{
[OperationContract]
[WebInvoke(UriTemplate = "CreateEmptyRecycleTask?emptyStation={line}", Method = "Get",
BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
Result CreateEmptyRecycleTask(string line);
//log4net.Config.XmlConfigurator.Configure();
// TODO: 在此添加您的服务操作
}
//[ServiceContract]
//public interface IWebService_Callback
//{
// [OperationContract(IsOneWay = true)]
// void GetEmptyRecycleTask(string lineName);
//}
// 使用下面示例中说明的数据约定将复合类型添加到服务操作。
[DataContract]
public class Result
{
[DataMember]
public string Succeed { get; set; }
[DataMember]
public string ResultData { get; set; }
[DataMember]
public string ErrorMessage { get; set; }
}
}
<Project ToolsVersion="15.0" DefaultTargets="Build" 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>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{074D4597-8955-4EEE-840A-8FAA9B174603}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>WebService</RootNamespace>
<AssemblyName>WebService</AssemblyName>
<ProjectTypeGuids>{3D9AD99F-2412-4246-B90B-4EAA41C64699};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<StartArguments>/client:"WcfTestClient.exe"</StartArguments>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<WcfConfigValidationEnabled>True</WcfConfigValidationEnabled>
<XsdCodeGenEnabled>True</XsdCodeGenEnabled>
</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="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>bin\Debug\log4net.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.ServiceModel.Web" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Compile Include="IWebService.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ClsWebService.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<VSToolsPath Condition="'$(VSToolsPath)' == '' and '$(VisualStudioVersion)' != '' and '$(VisualStudioVersion)' != '11.0'">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio</VSToolsPath>
<WcfServiceModelTargetPath>$(VSToolsPath)\WCF</WcfServiceModelTargetPath>
</PropertyGroup>
<Import Project="$(WcfServiceModelTargetPath)\Microsoft.VisualStudio.ServiceModel.targets" />
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{3D9AD99F-2412-4246-B90B-4EAA41C64699}">
<WcfProjectProperties>
<AutoStart>True</AutoStart>
</WcfProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
\ No newline at end of file \ No newline at end of file
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("WebService")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("WebService")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
//将 ComVisible 设置为 false 将使此程序集中的类型
//对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("074d4597-8955-4eee-840a-8faa9b174603")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
文件属性发生变化
using BLL.BLL;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace BLL
{
public class AGVManager
{
//public static string Add_emptyMsg = "http://10.85.199.1/BenQMIR/Webservice/AGVService.asmx/CreateEmptyRecycleTask";//"http://localhost:11111/BenQMIR/Webservice/AGVService.asmx/CreateEmptyRecycleTask";//
public static string CreateEmptyTask(string Add_emptyMsg, string line)
{
try
{
//Dictionary<string, string> paramMap = new Dictionary<string, string>();
//paramMap.Add("emptyStation", "D1");
string path = Add_emptyMsg;
//foreach (string paramName in paramMap.Keys)
//{
// string par = System.Web.HttpUtility.UrlEncode(paramMap[paramName], System.Text.Encoding.UTF8);
// path += paramName + "=" + par + "&";
//}
//path = path.Substring(0, path.Length - 1);
string resultStr = HttpUtil.Post(path, "emptyStation=" + line);//HttpHelper.Post(path, "");
//Common.log.Debug("【" + path + "】【" + resultStr + "】");
//Result data = JsonHelper.DeserializeJsonToObject<Result>(resultStr);
return resultStr;
//if (data == null)
//{
// return " updateDeviceAlarmMsg 没有收到服务器反馈";
//}
//else
//{
// return data.Succeed;
//}
}
catch (Exception e)
{
return e.ToString();
}
}
public static Result GetWebservice(string Add_emptyMsg,string id)
{
Result rb = new Result();
try
{
//http://10.85.36.156/BenQMIR/Webservice/AGVService.asmx
string strURL = Add_emptyMsg + "?emptyStation=" + id;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strURL);
//request.Method="get";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream s = response.GetResponseStream();
XmlTextReader Reader = new XmlTextReader(s);
Reader.MoveToContent();
string strValue = Reader.ReadInnerXml();
strValue = strValue.Replace("&lt;", "<");
strValue = strValue.Replace("&gt;", ">");
//{"Succeed":false,"ResultData":null,"ErrorMessage":"无法通过[Feederaaaa]lineCode找到小车停靠点"}
rb = JsonConvert.DeserializeObject<Result>(strValue);
Reader.Close();
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show(e.Message);
}
return rb;
}
/// <summary>
/// 获取大料架解绑情况
/// </summary>
/// <param name="rfid"></param>
/// <param name="lineName"></param>
/// <returns></returns>
public static bool GetRackBy(string rfid, out string lineName)
{
lineName = "";
//GET /ESMTCommonInterface/CommonService.asmx/GetRackBy?id=string HTTP/1.1
//Host: 10.85.17.233
string addr = "http://10.85.17.233/ESMTCommonInterface/CommonService.asmx/GetRackBy?id=" + rfid;
//[{"msg":"1OKD1"}]
//[{"msg":"0NGFeeder"}]
try
{
string result = HttpUtil.Get(addr);
if (!result.Equals(""))
{
List<Msg> msgs = JsonHelper.DeserializeJsonToList<Msg>(result);
if (msgs == null || msgs.Count == 0)
return false;
int.TryParse(msgs[0].msg.Substring(0, 1), out int resCode);
string resStr = msgs[0].msg.Substring(1, 2);
lineName = msgs[0].msg.Substring(3);
//Common.log.Debug(string.Format("resCode={0},resStr={1},lineName={2}", resCode, resStr, lineName));
if (lineName.Equals("").Equals(true))
return false;
return true;
}
}
catch { return false; }
return false;
}
/// <summary>
/// 物料状态上报
/// </summary>
/// <param name="rfid"></param>
/// <param name="lineName"></param>
/// <returns></returns>
public static bool UpdateStatus(string rfid, string lineName)
{
//GET /ESMTCommonInterface/CommonService.asmx/UpdateStatusBy?id=string&location=string HTTP/1.1
//Host: 10.85.17.233
string addr = "http://10.85.17.233/ESMTCommonInterface/CommonService.asmx/UpdateStatusBy?id=" + rfid + "&location=" + lineName;
//[{"msg":"1更新成功"}]
try
{
string result = HttpUtil.Get(addr);
if (!result.Equals(""))
{
List<Msg> msgs = JsonHelper.DeserializeJsonToList<Msg>(result);
if (msgs == null || msgs.Count == 0)
return false;
bool resRtn = int.TryParse(msgs[0].msg.Substring(0, 1), out int resCode);
if (resRtn)
{
if (resCode.Equals(1))
{
System.Windows.Forms.MessageBox.Show(string.Format("{0}物料状态更新成功[{1}]", lineName, rfid));
return true;
}
else
return false;
}
return false;
}
}
catch { return false; }
return false;
}
private class Msg
{
public string msg { get; set; }
}
}
public class Result
{
public string Succeed { get; set; }
public string ResultData { get; set; }
public string ErrorMessage { get; set; }
}
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
</appSettings>
<system.web>
<compilation debug="true"/>
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<protocolMapping>
<add scheme="https" binding="basicHttpsBinding" />
</protocolMapping>
<bindings>
<webHttpBinding>
<binding name="webBinding" maxReceivedMessageSize="2147483647" crossDomainScriptAccessEnabled="true" >
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="LineWebService.ClsWebService" behaviorConfiguration="RESTBehavior">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:22222/BenQMIR/Webservice/AGVService.asmx/" />
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address =""
binding="webHttpBinding"
contract="LineWebService.IWebService"
behaviorConfiguration="ESEndPointBehavior">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<!-- Metadata Endpoints -->
<!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
<!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="RESTBehavior">
<!-- To avoid disclosing metadata information,
set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="True"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="ESEndPointBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
</configuration>
namespace WebServiceTest
{
partial class Form1
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.button3 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.textBox2 = new System.Windows.Forms.TextBox();
this.textBox3 = new System.Windows.Forms.TextBox();
this.button4 = new System.Windows.Forms.Button();
this.button5 = new System.Windows.Forms.Button();
this.button6 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(12, 12);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(132, 54);
this.button1.TabIndex = 0;
this.button1.Text = "监听";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(12, 90);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(132, 54);
this.button2.TabIndex = 1;
this.button2.Text = "关闭";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(26, 187);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(55, 15);
this.label1.TabIndex = 2;
this.label1.Text = "label1";
//
// button3
//
this.button3.Location = new System.Drawing.Point(273, 90);
this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(132, 54);
this.button3.TabIndex = 3;
this.button3.Text = "POST访问";
this.button3.UseVisualStyleBackColor = true;
this.button3.Click += new System.EventHandler(this.button3_Click);
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(150, 12);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(497, 72);
this.textBox1.TabIndex = 4;
this.textBox1.Text = "http://10.85.199.1/BenQMIR/Webservice/AGVService.asmx/CreateEmptyRecycleTask";
//
// textBox2
//
this.textBox2.Location = new System.Drawing.Point(160, 119);
this.textBox2.Name = "textBox2";
this.textBox2.Size = new System.Drawing.Size(79, 25);
this.textBox2.TabIndex = 5;
this.textBox2.Text = "D1";
//
// textBox3
//
this.textBox3.Location = new System.Drawing.Point(150, 176);
this.textBox3.Multiline = true;
this.textBox3.Name = "textBox3";
this.textBox3.Size = new System.Drawing.Size(497, 160);
this.textBox3.TabIndex = 6;
//
// button4
//
this.button4.Location = new System.Drawing.Point(443, 90);
this.button4.Name = "button4";
this.button4.Size = new System.Drawing.Size(132, 54);
this.button4.TabIndex = 7;
this.button4.Text = "feeder区访问";
this.button4.UseVisualStyleBackColor = true;
this.button4.Click += new System.EventHandler(this.button4_Click);
//
// button5
//
this.button5.Location = new System.Drawing.Point(592, 90);
this.button5.Name = "button5";
this.button5.Size = new System.Drawing.Size(132, 54);
this.button5.TabIndex = 8;
this.button5.Text = "大料架回收访问";
this.button5.UseVisualStyleBackColor = true;
this.button5.Click += new System.EventHandler(this.button5_Click);
//
// button6
//
this.button6.Location = new System.Drawing.Point(735, 41);
this.button6.Name = "button6";
this.button6.Size = new System.Drawing.Size(132, 54);
this.button6.TabIndex = 9;
this.button6.Text = "物料状态上报";
this.button6.UseVisualStyleBackColor = true;
this.button6.Click += new System.EventHandler(this.button6_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(879, 368);
this.Controls.Add(this.button6);
this.Controls.Add(this.button5);
this.Controls.Add(this.button4);
this.Controls.Add(this.textBox3);
this.Controls.Add(this.textBox2);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.button3);
this.Controls.Add(this.label1);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "客户端创建产线任务";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.TextBox textBox2;
private System.Windows.Forms.TextBox textBox3;
private System.Windows.Forms.Button button4;
private System.Windows.Forms.Button button5;
private System.Windows.Forms.Button button6;
}
}
using LineWebService;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.ServiceModel.Web;
using System.ServiceModel;
using System.Linq.Expressions;
using BLL;
namespace WebServiceTest
{
public partial class Form1 : Form//, IWebService_Callback
{
public Form1()
{
InitializeComponent();
}
private WebServiceHost _serviceHost;
public void HostOpen()
{
try
{
ClsWebService service = new ClsWebService();
_serviceHost = new WebServiceHost(typeof(ClsWebService));//service, new Uri(url)
if (_serviceHost.State != CommunicationState.Opened)//判断服务是否关闭
{
_serviceHost.Open();
}
label1.Text="Web服务已开启";
}
catch (Exception ex)
{
//AGVControl.Common.log.Error("Open", ex);
MessageBox.Show(ex.ToString());
}
}
public void HostClose()
{
try
{
if (_serviceHost.State != CommunicationState.Closed)//判断服务是否关闭
{
_serviceHost.Close();//关闭服务
}
//_serviceHost.Close();
label1.Text="Web服务已关闭";
}
catch (Exception ex)
{
//AGVControl.Common.log.Error("Close", ex);
MessageBox.Show(ex.ToString());
}
}
//public void GetEmptyRecycleTask(string lineName)
//{
// label1.Text = lineName;
// MessageBox.Show(lineName);
//}
public void RecycleTask(string lineName)
{
label1.Text = lineName;
MessageBox.Show(lineName);
//if (AGVControl.Common.agvProductionLine.TryGetValue(lineName, out string value))
//{
// AGVControl.Common.LogInfo("WebService Response OK");
// //加到任务
// //int idx = AGVControl.Common.nodeInfo.FindIndex(s => s.Name == value);
// //if (idx > -1)
// // AGVControl.Common.linePlace.Add(value);
// //else
// // AGVControl.Common.log.Error("CreateEmptyRecycleTask " + value + "不存在");
// if (!Common.AddLinePlace(value))
// Common.log.Error("CreateEmptyRecycleTask 节点【" + value + "】不存在");
// else
// {
// Common.LogInfo("任务:" + value + " 出空料架 【" + lineName + "】");
// }
// //System.IO.File.WriteAllLines(Common.CONFIG_PATH + "LinePlace.txt", Common.linePlace);
//}
//else
//{
// AGVControl.Common.LogInfo("WebService Response false");
//}
}
private void button1_Click(object sender, EventArgs e)
{
HostOpen();
}
private void button2_Click(object sender, EventArgs e)
{
HostClose();
}
private void button3_Click(object sender, EventArgs e)
{
textBox3.Text=AGVManager.CreateEmptyTask(textBox1.Text,textBox2.Text);
}
private void button4_Click(object sender, EventArgs e)
{
AGVManager.GetWebservice(textBox1.Text, textBox2.Text);
}
private void button5_Click(object sender, EventArgs e)
{
bool qq = AGVManager.GetRackBy(textBox1.Text, out string kk);
textBox2.Text = qq.ToString() +" "+kk;
}
private void button6_Click(object sender, EventArgs e)
{
AGVManager.UpdateStatus("D17", "D1");
}
}
}
<?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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
\ No newline at end of file \ No newline at end of file
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Collections;
using System.Net;
using System.Net.Security;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Reflection;
using System.Net.NetworkInformation;
using BLL;
namespace BLL
{
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Collections;
using System.Net;
using System.Net.Security;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Reflection;
using log4net;
using Newtonsoft.Json;
using System.Windows.Forms;
namespace BLL
{
public class HttpUtil
{
public static readonly ILog LOGGER = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public static string Post(string url, string paramData)
{
return Post(url, paramData, Encoding.UTF8);
}
public static T ObjPost<T>(string url, object o) where T : class
{
try
{
string json = JsonUtil.SerializeObject(o);
string result = Post(url, json);
if (!string.IsNullOrEmpty(result))
{
return JsonUtil.DeserializeJsonToObject<T>(result);
}
}
catch (Exception ex)
{
LOGGER.Error("Http post 出错" + ex);
}
return default(T);
}
public static List<T> ListPost<T>(string url, object o) where T : class
{
try
{
string json = JsonUtil.SerializeObject(o);
string result = Post(url, json);
if (!string.IsNullOrEmpty(result))
{
return JsonUtil.DeserializeJsonToList<T>(result);
}
}
catch (Exception ex)
{
LOGGER.Error("Http post 出错" + ex);
}
return new List<T>();
}
public static string Post(string url, string paramData, Encoding encoding)
{
string result = "";
if (url.ToLower().IndexOf("https", System.StringComparison.Ordinal) > -1)
{
ServicePointManager.ServerCertificateValidationCallback =
new RemoteCertificateValidationCallback((sender, certificate, chain, errors) => { return true; });
}
try
{
var wc = new TimeoutWebClient(5000);
if (string.IsNullOrEmpty(wc.Headers["Content-Type"]))
//wc.Headers.Add("Content-Type", "application/json;charset=UTF-8");
//如果需要将body中的参数以key/value格式发送到服务器,使用下面的Header
wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
wc.Encoding = encoding;
//paramData = Uri.EscapeDataString(paramData);
result = wc.UploadString(url, "POST", paramData);
//LogUtil.info(result);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
LOGGER.Error("POST【" + paramData + "】 ERROR:", e);
}
//LOGGER.Info("post receive <<" + result );
return result;
}
public static string Get(string url)
{
return Get(url, Encoding.UTF8);
}
public static string Get(string url, Encoding encoding)
{
try
{
LOGGER.Info("HTTP GET FROM: " + url);
var wc = new WebClient { Encoding = encoding };
var readStream = wc.OpenRead(url);
using (var sr = new StreamReader(readStream, encoding))
{
var result = sr.ReadToEnd();
LOGGER.Info("get receive << " + result);
return result;
}
}
catch (Exception e)
{
LOGGER.Error("HTTP GET ERROR:", e);
}
return "";
}
}
/// <summary>
/// Json帮助类
/// </summary>
public class JsonUtil
{
/// <summary>
/// 将对象序列化为JSON格式
/// </summary>
/// <param name="o">对象</param>
/// <returns>json字符串</returns>
public static string SerializeObject(object o)
{
string json = JsonConvert.SerializeObject(o);
return json;
}
/// <summary>
/// 解析JSON字符串生成对象实体
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="json">json字符串(eg.{"ID":"112","Name":"石子儿"})</param>
/// <returns>对象实体</returns>
public static T DeserializeJsonToObject<T>(string json) where T : class
{
JsonSerializer serializer = new JsonSerializer();
StringReader sr = new StringReader(json);
object o = serializer.Deserialize(new JsonTextReader(sr), typeof(T));
T t = o as T;
return t;
}
/// <summary>
/// 解析JSON数组生成对象实体集合
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="json">json数组字符串(eg.[{"ID":"112","Name":"石子儿"}])</param>
/// <returns>对象实体集合</returns>
public static List<T> DeserializeJsonToList<T>(string json) where T : class
{
JsonSerializer serializer = new JsonSerializer();
StringReader sr = new StringReader(json);
object o = serializer.Deserialize(new JsonTextReader(sr), typeof(List<T>));
List<T> list = o as List<T>;
return list;
}
/// <summary>
/// 反序列化JSON到给定的匿名对象.
/// </summary>
/// <typeparam name="T">匿名对象类型</typeparam>
/// <param name="json">json字符串</param>
/// <param name="anonymousTypeObject">匿名对象</param>
/// <returns>匿名对象</returns>
public static T DeserializeAnonymousType<T>(string json, T anonymousTypeObject)
{
T t = JsonConvert.DeserializeAnonymousType(json, anonymousTypeObject);
return t;
}
}
public class TimeoutWebClient : WebClient
{
private int _timeout;
/// <summary>
/// 超时时间(毫秒)
/// </summary>
public int Timeout
{
get
{
return _timeout;
}
set
{
_timeout = value;
}
}
public TimeoutWebClient()
{
this._timeout = 60000;
}
public TimeoutWebClient(int timeout)
{
this._timeout = timeout;
}
protected override WebRequest GetWebRequest(Uri address)
{
var result = base.GetWebRequest(address);
result.Timeout = this._timeout;
return result;
}
}
}
}
\ No newline at end of file \ No newline at end of file
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
namespace BLL
{
/// <summary>
/// Json帮助类
/// </summary>
public class JsonHelper
{
/// <summary>
/// 将对象序列化为JSON格式
/// </summary>
/// <param name="o">对象</param>
/// <returns>json字符串</returns>
public static string SerializeObject(object o)
{
string json = JsonConvert.SerializeObject(o);
return json;
}
/// <summary>
/// 解析JSON字符串生成对象实体
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="json">json字符串(eg.{"ID":"112","Name":"石子儿"})</param>
/// <returns>对象实体</returns>
public static T DeserializeJsonToObject<T>(string json) where T : class
{
JsonSerializer serializer = new JsonSerializer();
StringReader sr = new StringReader(json);
object o = serializer.Deserialize(new JsonTextReader(sr), typeof(T));
T t = o as T;
return t;
}
/// <summary>
/// 解析JSON数组生成对象实体集合
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="json">json数组字符串(eg.[{"ID":"112","Name":"石子儿"}])</param>
/// <returns>对象实体集合</returns>
public static List<T> DeserializeJsonToList<T>(string json) where T : class
{
JsonSerializer serializer = new JsonSerializer();
StringReader sr = new StringReader(json);
object o = serializer.Deserialize(new JsonTextReader(sr), typeof(List<T>));
List<T> list = o as List<T>;
return list;
}
/// <summary>
/// 反序列化JSON到给定的匿名对象.
/// </summary>
/// <typeparam name="T">匿名对象类型</typeparam>
/// <param name="json">json字符串</param>
/// <param name="anonymousTypeObject">匿名对象</param>
/// <returns>匿名对象</returns>
public static T DeserializeAnonymousType<T>(string json, T anonymousTypeObject)
{
T t = JsonConvert.DeserializeAnonymousType(json, anonymousTypeObject);
return t;
}
}
///// <summary>
///// 与服务器通信用对象
///// </summary>
//public class Operation
//{
// private string _cid = "";
// public string cid
// {
// get { return _cid; }
// set { _cid = value; }
// }
// public int seq { get; set; }
// public int op { get; set; }
// public int status { get; set; }
// private string _error = "";
// public string error
// {
// get { return _error; }
// set { _error = value; }
// }
// private Dictionary<string, string> _data = new Dictionary<string,string>();
// public Dictionary<string, string> data {
// get { return _data; }
// set { _data = value; }
// }
//}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
namespace BLL
{
public class MyWebClient:WebClient
{
private int _timeout;
/// <summary>
/// 超时时间(毫秒)
/// </summary>
public int Timeout
{
get
{
return _timeout;
}
set
{
_timeout = value;
}
}
public MyWebClient()
{
this._timeout = 60000;
}
public MyWebClient(int timeout)
{
this._timeout = timeout;
}
protected override WebRequest GetWebRequest(Uri address)
{
var result = base.GetWebRequest(address);
result.Timeout = this._timeout;
return result;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WebServiceTest
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("WebServiceTest")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("WebServiceTest")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("a89f6ec4-457a-4998-acdc-f1adc22c8bf8")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio .Net. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="Result" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>LineWebService.Result, WebService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>
\ No newline at end of file \ No newline at end of file
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本: 4.0.30319.42000
//
// 对此文件的更改可能导致不正确的行为,如果
// 重新生成代码,则所做更改将丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace WebServiceTest.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("WebServiceTest.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;
}
}
}
}
<?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>
\ No newline at end of file \ No newline at end of file
//------------------------------------------------------------------------------
// <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 WebServiceTest.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;
}
}
}
}
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>
<?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>{A89F6EC4-457A-4998-ACDC-F1ADC22C8BF8}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>WebServiceTest</RootNamespace>
<AssemblyName>WebServiceTest</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<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' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>bin\Debug\log4net.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>bin\Debug\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.ServiceModel.Web" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="WebService">
<HintPath>..\WebService\bin\Debug\WebService.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="AGVManager.cs" />
<Compile Include="Form1.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<Compile Include="HttpHelper.cs" />
<Compile Include="JsonHelper.cs" />
<Compile Include="MyWebClient.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<None Include="Properties\DataSources\LineWebService.Result.datasource" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<WCFMetadata Include="Connected Services\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file \ No newline at end of file
文件属性发生变化
文件属性发生变化
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!