diff --git a/Aucma.Core.CodeBinding/ViewModels/IndexPageViewModel.cs b/Aucma.Core.CodeBinding/ViewModels/IndexPageViewModel.cs
index 3cf647ec..e311d046 100644
--- a/Aucma.Core.CodeBinding/ViewModels/IndexPageViewModel.cs
+++ b/Aucma.Core.CodeBinding/ViewModels/IndexPageViewModel.cs
@@ -262,6 +262,8 @@ namespace Aucma.Core.CodeBinding.ViewModels
}
#region plc交互
+
+ private SemaphoreSlim semaphore = new SemaphoreSlim(0);
///
/// 下发plc放行信号
///
@@ -280,6 +282,7 @@ namespace Aucma.Core.CodeBinding.ViewModels
obj.plc.WriteInt32("D100", 1);
// 等待plc反馈信号
waitPlcSignal();
+ semaphore.Wait();
result = true;
}
else
@@ -328,6 +331,10 @@ namespace Aucma.Core.CodeBinding.ViewModels
Thread.Sleep(1000);
} while (isFlag);
+
+ // 释放信号量
+ semaphore.Release();
+
}
else
{
diff --git a/Aucma.Core.ProductOffLine/Startup.cs b/Aucma.Core.ProductOffLine/Startup.cs
index a8468c04..19d29bf5 100644
--- a/Aucma.Core.ProductOffLine/Startup.cs
+++ b/Aucma.Core.ProductOffLine/Startup.cs
@@ -7,6 +7,7 @@ using Admin.Core.Model;
using Admin.Core.Repository;
using Admin.Core.Service;
using Admin.Core.Tasks;
+using Aucma.Core.RunPlc;
using Aucma.Core.Scanner;
using Autofac;
using Microsoft.AspNetCore.Builder;
@@ -45,7 +46,7 @@ namespace Aucma.Core.ProductOffLine
/// This method gets called by the runtime. Use this method to add services to the container.
///
///
- public void ConfigureServices(IServiceCollection services)
+ public async void ConfigureServices(IServiceCollection services)
{
//Appsettings
services.AddSingleton(new Appsettings(Configuration));
@@ -61,10 +62,15 @@ namespace Aucma.Core.ProductOffLine
//עҵ
AddServices(services);
- //
- services.AddJobSetup();
//ɨ
services.AddScannerSetup();
+
+ //
+ // services.AddJobSetup();
+
+ //PLC
+ services.AddPlcSetup();
+
//ֱ֧ȫ :֧ System.Text.Encoding.GetEncoding("GB2312") System.Text.Encoding.GetEncoding("GB18030")
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
}
@@ -85,8 +91,7 @@ namespace Aucma.Core.ProductOffLine
///
///
///
- public void Configure(IApplicationBuilder app, ISysTasksQzService tasksQzService,
- ISchedulerCenter schedulerCenter, IScannerService scannerService)
+ public void Configure(IApplicationBuilder app, IScannerService scannerService, IRunPlcService runPlcService)
{
// ʹþ̬ļ
app.UseStaticFiles();
@@ -94,9 +99,11 @@ namespace Aucma.Core.ProductOffLine
//app.UseAuthorization();
// QuartzNetJobȷ
- app.UseQuartzJobMildd(tasksQzService, schedulerCenter);
+ // app.UseQuartzJobMildd(tasksQzService, schedulerCenter);
//ɨ
app.UseScannerMildd(scannerService);
+ //PLC
+ app.UsePlcMildd(runPlcService);
}
#region ע
diff --git a/Aucma.Core.ProductOffLine/ViewModels/IndexPageViewModel.cs b/Aucma.Core.ProductOffLine/ViewModels/IndexPageViewModel.cs
index 15cc4167..bbc1fac9 100644
--- a/Aucma.Core.ProductOffLine/ViewModels/IndexPageViewModel.cs
+++ b/Aucma.Core.ProductOffLine/ViewModels/IndexPageViewModel.cs
@@ -14,6 +14,9 @@ using static Aucma.Core.Scanner.MvCodeHelper;
using Admin.Core.Common;
using System.Linq;
using static Npgsql.Replication.PgOutput.Messages.RelationMessage;
+using Aucma.Core.PLc;
+using System.Threading.Tasks;
+using Consul;
/*
* 成品分舵入库首页信息
@@ -24,15 +27,17 @@ namespace Aucma.Core.ProductOffLine.ViewModels
public partial class IndexPageViewModel : ObservableObject
{
private static readonly log4net.ILog log = LogManager.GetLogger(typeof(IndexPageViewModel));
-
+
+
public IndexPageViewModel()
{
MvCodeHelper.ReceiveCodeEvent += ReceiveCode;
+
// test();
//List listdatabase = Appsettings.app("DBS")
// .Where(i => i.Enabled).ToList();
- InitEveryDayMethod();
-
+ InitEveryDayMethod();
+ test2();
}
#region 扫描信息
@@ -207,15 +212,22 @@ namespace Aucma.Core.ProductOffLine.ViewModels
private void ReceiveCode(string code,int direction)
{
//1.扫描的SN条码去条码系统查询GET_BARCODE_DATA
+
string result = "Y@1104@16160030000000910780@000010034895@@ @000000@000000009000000807@BCD-160C,家电下乡@@BCD-160C@皓月白-家电下乡@161601300@160@1-00版@家电下乡产品@默认@2010-09-01";
+ // 如果校验失败,下发报警
+ if("N".Equals(result.Substring(0,1)))
+ {
+ sendPlcError();
+ // 刷新页面提示信息 result.Substring(2)
+ return;
+ }
//2.查询到的数据分割处理,结果中用"@"号分隔,刷新页面显示并存到scada数据库(表待建)
string[] resultArray = result.Split('@');
// 输出结果
foreach (string item in resultArray)
{
-
- MessageBox.Show(item);
+ Console.WriteLine(item);
}
//3.调条码系统保存接口入库SaveBarcodeInfo
@@ -225,20 +237,141 @@ namespace Aucma.Core.ProductOffLine.ViewModels
//5.分垛A,B库逻辑(先左边读到的条码分A库,右边读到的B库==>预留分库逻辑)
//6.下发plc信号
- sendPlc();
+ SendPlcPass(direction);
}
+ #region plc交互
+
+ private SemaphoreSlim semaphore = new SemaphoreSlim(0);
+ ///
+ /// 下发plc放行信号
+ ///
+ ///
+ private bool SendPlcPass(int direction)
+ {
+ bool result = false;
+ try
+ {
+ var obj = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("成品下线Plc"));
+ if (obj != null)
+ {
+ if (obj.plc.IsConnected)
+ {
+ // 写入入库方向
+ obj.plc.WriteInt32("D100", direction);
+ // 往plc写入放行信号
+ obj.plc.WriteInt32("D102", 1);
+ // 等待plc反馈信号
+ waitPlcSignal();
+ semaphore.Wait();
+ result = true;
+ }
+ else
+ {
+ log.Info("成品下线plc连接失败,请检查plc连接");
+ }
+ }
+ else
+ {
+ log.Info("获取plc连接对象信息为空");
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("下发plc放行信号方法SendPlcPass()出现异常,ex:" + ex);
+ }
+ return result;
+ }
///
- /// plc信号下发
+ /// 读取plc放行反馈
///
- private void sendPlc()
+ ///
+ private void waitPlcSignal()
{
+ try
+ {
+ lock (string.Empty)
+ {
+ bool isFlag = true;
+ var obj = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("成品下线Plc"));
+ Task.Run(() =>
+ {
+ if (obj != null)
+ {
+ if (obj.plc.IsConnected)
+ {
+ do
+ {
+ // 读取plc反馈信号
+ if (obj.plc.ReadInt32("D102") == 2)
+ {
+ Console.WriteLine("收到plc放行成功");
+ // 清空数据
+ obj.plc.WriteInt32("D100", 0);
+ obj.plc.WriteInt32("D102", 0);
+ isFlag = false;
+ }
+ Thread.Sleep(1000);
+ } while (isFlag);
+ // 释放信号量
+ semaphore.Release();
+ }
+ else
+ {
+ log.Info("成品下线plc连接失败,请检查plc连接");
+ }
+ }
+ else
+ {
+ log.Info("获取plc连接对象信息为空");
+ }
+ });
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("读取plc放行反馈方法waitPlcSignal()出现异常,ex:" + ex);
+ }
}
- // 测试连接
+ ///
+ /// 下发plc报警信号
+ ///
+ private void sendPlcError()
+ {
+ try
+ {
+ var obj = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("成品下线Plc"));
+ if (obj != null)
+ {
+ if (obj.plc.IsConnected)
+ {
+ // 下发报警信号
+ obj.plc.WriteInt32("D104", 1);
+ }
+ else
+ {
+ log.Info("成品下线plc连接失败,请检查plc连接");
+ }
+ }
+ else
+ {
+ log.Info("获取plc连接对象信息为空");
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("下发plc放报警信号方法sendPlcError()出现异常,ex:" + ex);
+ }
+ }
+ #endregion
+
+ ///
+ /// 连接测试
+ ///
void test()
{
string connectionString = "Data Source=(DESCRIPTION=(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.1.50)(PORT = 1521)))(CONNECT_DATA=(SERVICE_NAME=tmdata)));User ID=ILS_SORT;Password=Aucma_2019;";
@@ -266,5 +399,19 @@ namespace Aucma.Core.ProductOffLine.ViewModels
}
}
}
+
+ ///
+ /// 测试
+ ///
+ private async void test2()
+ {
+ Task.Run(() =>
+ {
+ Thread.Sleep(2000);
+ SendPlcPass(1);
+ Thread.Sleep(1000);
+ SendPlcPass(2);
+ });
+ }
}
}
diff --git a/Aucma.Core.ProductOffLine/ViewModels/StatisticsPageViewModel.cs b/Aucma.Core.ProductOffLine/ViewModels/StatisticsPageViewModel.cs
index 5b3b62a4..8bc655d8 100644
--- a/Aucma.Core.ProductOffLine/ViewModels/StatisticsPageViewModel.cs
+++ b/Aucma.Core.ProductOffLine/ViewModels/StatisticsPageViewModel.cs
@@ -32,7 +32,6 @@ namespace Aucma.Core.ProductOffLine.ViewModels
MaterialDataGrid.Add(new MaterialComplateInfo() { No = 10, ProductPlanCode = "8659452123", MaterialCode = "8659452123", MaterialName = "SC-AUCMA-农夫山泉,SC", PlanAmount = 50, CompleteAmount = 10});
}
-
#endregion
#region 初始化datagrid
diff --git a/Aucma.Core.ProductOffLine/appsettings.json b/Aucma.Core.ProductOffLine/appsettings.json
index 113f7c8b..6e3873c4 100644
--- a/Aucma.Core.ProductOffLine/appsettings.json
+++ b/Aucma.Core.ProductOffLine/appsettings.json
@@ -194,10 +194,30 @@
"QuartzNetJob": {
"Enabled": true
},
- "Scanner": {//扫码器
+ "Scanner": { //扫码器
"Enabled": true
+ },
+ "Scanner1": { //扫码器1
+ "Ip": "192.168.1.19",
+ "Name": "扫码器1"
+ },
+ "Scanner2": { //扫码器2
+ "Ip": "192.168.1.20",
+ "Name": "扫码器2"
+ },
+ "ScannerGun": { //扫码枪
+ "Enabled": false
}
},
+ "PLCServer": [
+ {
+ "Id": 1,
+ "EquipName": "成品下线Plc",
+ "IP": "127.0.0.1",
+ "Port": 6000
+ }
+
+ ],
"IpRateLimiting": {
"EnableEndpointRateLimiting": false, //False: globally executed, true: executed for each
"StackBlockedRequests": false, //False: Number of rejections should be recorded on another counter
@@ -245,4 +265,5 @@
}
]
}
+
}