using HH.WCS.JiaTong.api;
using Microsoft.Owin.BuilderProperties;
using Newtonsoft.Json.Linq;
using Opc.UaFx;
using S7.Net;
using S7.Net.Types;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Services.Description;
using System.Web.UI.WebControls.WebParts;
namespace HH.WCS.JiaTong.device
{
///
/// 西门子plc
///
public class S7Helper
{
private static bool debug = true;
private static S7.Net.Plc plc = null;
static S7Helper()
{
Init();
}
private static Dictionary plcDic = new Dictionary();
private static void Init()
{
//配置文件读取所有的plc进行初始化
try
{
var plc1 = new Plc(CpuType.S71500, "", 0, 1);
plcDic.Add("plc1", plc1);
Link(plc1);
}
catch (Exception ex)
{
Console.WriteLine("S7Helper Init err=" + ex.Message);
}
}
private static Plc GetPlc(string plc)
{
if (plcDic.ContainsKey(plc))
{
return plcDic[plc];
}
else
{
return null;
}
}
public static Dictionary s7TestData = new Dictionary();
private static void Link(Plc plc)
{
try
{
if (!plc.IsConnected)
{
plc.Close();
plc.Open();
if (plc.IsConnected)
{
Console.WriteLine($"已连接到plc{plc.IP}");
}
else
{
//Console.WriteLine($"plc{plc.IP}连接失败");
LogHelper.Info($"plc{plc.IP}连接失败", "Plc");
}
}
}
catch (Exception ex)
{
// Console.WriteLine($"plc{plc.IP}连接失败,err={ex.Message}");
LogHelper.Error($"Link Error plc{plc.IP}连接失败,err={ex.Message}",ex);
//Init();
}
}
//https://www.ad.siemens.com.cn/productportal/Prods/S7-1200_PLC_EASY_PLUS/SmartSMS/060.html
//https://www.ad.siemens.com.cn/productportal/Prods/S7-1200_PLC_EASY_PLUS/07-Program/02-basic/01-Data_Type/09-String.html
private static object _lockdpj=new object();
///
/// 合肥佳通读取叠盘机
///
/// 偏移量地址 vb2001
/// /// 值类型
///
public static int ReadDpj(string ip,int startByte, S7.Net.VarType varType)
{
// string ip = "10.68.9.15";
short port = 102;
lock (_lockdpj)
{
try
{
var plc = new Plc(CpuType.S7200Smart, ip, port, 0, 0);
LogHelper.Info($"链接叠盘机,ip:{ip},端口:{port}");
S7Helper.Link(plc);
int result = 0;
if (varType == VarType.Int)
{
var value = (short)plc.Read(DataType.DataBlock, 1, startByte, VarType.Int, 1);
LogHelper.Info($"链接叠盘机,ip:{ip},端口:{port},读取类型{varType},读取值{value}");
result = int.Parse(value.ToString());
}
else//合肥佳通除了数量,其他都是byte类型
{
byte value = (byte)plc.Read(DataType.DataBlock, 1, startByte, VarType.Byte, 1);
LogHelper.Info($"链接叠盘机,ip:{ip},端口:{port},读取类型{varType},读取值{value}");
result = value;
}
LogHelper.Info($"读取叠盘机,ip:{ip},端口:{port},地址:{startByte},读取值转换:{result}");
return result;
}
catch (Exception ex)
{
LogHelper.Error($"ReadDpj Error:{ex}", ex);
throw;
}
}
}
///
/// 合肥佳通写入叠盘机
///
/// 偏移量地址
/// 写入值 byte类型只能0 1
///
public static bool WriteDpj(string ip,int startByte, byte value)
{
bool result = false;
// string ip = "10.68.9.15";
short port = 102;
lock (_lockdpj)
{
try
{
var plc = new Plc(CpuType.S7200Smart, ip, port, 0, 0);
LogHelper.Info($"链接叠盘机,ip:{ip},端口:{port}");
S7Helper.Link(plc);
// plc.Write($"VB{startByte}", value);
Thread.Sleep(300);
plc.Write(
dataType: DataType.DataBlock,
db: 1,
startByteAdr: startByte,
value: value
);
LogHelper.Info($"写入叠盘机,ip:{ip},端口:{port},地址:{startByte},写入值:{value}");
Thread.Sleep(300);
byte fdvalue = (byte)plc.Read(DataType.DataBlock, 1, startByte, VarType.Byte, 1);
if (fdvalue == value)
{
result = true;
LogHelper.Info($"叠盘机写入成功,回读值:{fdvalue}");
}
else
{
LogHelper.Info($"叠盘机写入失败,回读值:{fdvalue}");
}
return result;
}
catch (Exception ex)
{
LogHelper.Info($"WriteDpj Error{ex}");
throw;
}
}
// S7-200 Smart的V区也映射为DB1
}
internal static short[] ReadInt(string device, int db, int byteAddr, int count)
{
short[] result = null;
try
{
if (debug)
{
var s7Key = $"int_{db}_{byteAddr}_{count}";
if (s7TestData.ContainsKey(s7Key))
{
var data = s7TestData[s7Key].Split(',');
if (data.Length == count)
{
result = Array.ConvertAll(data, s => short.Parse(s));
}
else
{
result = new short[count];
s7TestData[s7Key] = string.Join(",", result);
}
Console.WriteLine($"读取plc {device}信息成功, addr={byteAddr} data={string.Join(",", result)}");
}
}
else
{
var plc = GetPlc(device);
if (plc != null)
{
if (plc.IsConnected)
{
result = (short[])plc.Read(DataType.DataBlock, db, byteAddr, VarType.Int, count, 0);
Console.WriteLine($"读取plc {device}信息成功,ip={plc.IP} addr={byteAddr} data={string.Join(",", result)}");
if (result.Length == 0)
{
Console.WriteLine($"plc {device}准备重新连接");
Link(plc);
}
}
else
{
Console.WriteLine($"准备连接plc {device}");
Link(plc);
}
}
else
{
Console.WriteLine($"plc {device}不存在");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"ReadInt,device={device} addr={byteAddr} count={count} err={ex.Message}");
LogHelper.Error($"ReadInt,device={device} addr={byteAddr} count={count} err={ex.Message}", ex);
}
return result;
}
///
///
///
///
///
///
///
internal static bool WriteInt(int db, int byteAddr, short data)
{
var result = false;
try
{
if (plc.IsConnected)
{
plc.Write(DataType.DataBlock, db, byteAddr, data);
Console.WriteLine($"写入plc信息,ip={plc.IP} addr={byteAddr} data={data} ");
LogHelper.Info($"写入plc信息,ip={plc.IP} addr={byteAddr} data={data} ");
if (result)
{
//写完再读一次确认
var readData = (short)plc.Read(DataType.DataBlock, db, byteAddr, VarType.Int, 1, 0);
Console.WriteLine($"读取plc信息,ip={plc.IP} addr={byteAddr} data={data} res={string.Join(", ", readData)}");
LogHelper.Info($"读取plc信息,ip={plc.IP} addr={byteAddr} data={data} res={string.Join(", ", readData)}", "PLC");
result = readData == data;
}
}
else
{
Console.WriteLine("准备连接plc1");
Link(plc);
}
}
catch (Exception ex)
{
LogHelper.Error($"写入plc1信息失败,ip={plc.IP} addr={byteAddr} data={data} err={ex.Message}", ex);
}
return result;
}
public static object ReadBit(string device, int db, int byteAddr, byte bitAddr)
{
object result = null;
try
{
if (debug)
{
var s7Key = $"bit_{db}_{byteAddr}_{bitAddr}";
if (s7TestData.ContainsKey(s7Key))
{
var data = s7TestData[s7Key];
if (data == "1")
{
result = true;
}
else { result = false; }
Console.WriteLine($"读取plc {device}信息成功, addr={byteAddr} data={result.ToString()}");
}
}
else
{
var plc = GetPlc(device);
if (plc != null)
{
if (plc.IsConnected)
{
result = plc.Read(DataType.DataBlock, db, byteAddr, VarType.Int, 1, bitAddr);
Console.WriteLine($"读取plc {device}信息成功,ip={plc.IP} addr={byteAddr} data={result.ToString()}");
}
else
{
Console.WriteLine($"准备连接plc {device}");
Link(plc);
}
}
else
{
Console.WriteLine($"plc {device}不存在");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"ReadBit,device={device} addr={byteAddr} bit={bitAddr} err={ex.Message}");
LogHelper.Error($"ReadBit,device={device} addr={byteAddr} bit={bitAddr} err={ex.Message}", ex);
}
return result;
}
public static string ReadStr(string device, int db, int byteAddr, int count)
{
string result = string.Empty;
try
{
if (debug)
{
var s7Key = $"str_{db}_{byteAddr}_{count}";
if (s7TestData.ContainsKey(s7Key))
{
var data = s7TestData[s7Key];
if (data.Length == count)
{
result = data;
Console.WriteLine($"ReadStr 成功, addr={byteAddr} res={result}");
}
}
}
else
{
if (plc.IsConnected)
{
result = plc.Read(DataType.DataBlock, 100, byteAddr, VarType.String, count, 0).ToString();
Console.WriteLine($"ReadStr 成功,ip={plc.IP} addr={byteAddr} res={result}");
if (result.Length == 0)
{
Link(plc);
}
}
else
{
Console.WriteLine("准备连接plc");
Link(plc);
}
}
}
catch (Exception ex)
{
Console.WriteLine($"ReadStr,device={device} addr={byteAddr} count={count} err={ex.Message}");
LogHelper.Error($"ReadStr,device={device} addr={byteAddr} count={count} err={ex.Message}", ex);
}
return result;
}
#region 用于模拟测试
///
/// short类型,一个占2个byte
///
public class DBWModel
{
public int db { get; set; }
public int byteAddr { get; set; }
///
/// int类型需要用逗号分开,string不需要
///
public string value { get; set; }
}
///
/// 字符串类型,一个占1个byte
///
public class DBBModel
{
public int db { get; set; }
public int byteAddr { get; set; }
public string value { get; set; }
}
public class DBXModel
{
public int db { get; set; }
public int byteAddr { get; set; }
public int bitAddr { get; set; }
///
/// 1:true 0:false
///
public int value { get; set; }
}
public static void s7SetInt(DBWModel model)
{
var data = model.value.Replace(",", "");
var s7Key = $"int_{model.db}_{model.byteAddr}_{data.Length}";
if (s7TestData.ContainsKey(s7Key))
{
s7TestData[s7Key] = model.value;
}
else
{
s7TestData.Add(s7Key, model.value);
}
}
internal static void s7SetBit(DBXModel model)
{
var s7Key = $"bit_{model.db}_{model.byteAddr}_{model.bitAddr}";
var value = model.value == 1 ? "1" : "0";
if (s7TestData.ContainsKey(s7Key))
{
s7TestData[s7Key] = value;
}
else
{
s7TestData.Add(s7Key, value);
}
}
internal static void s7SetStr(DBBModel model)
{
var s7Key = $"str_{model.db}_{model.byteAddr}_{model.value.Length}";
if (s7TestData.ContainsKey(s7Key))
{
s7TestData[s7Key] = model.value;
}
else
{
s7TestData.Add(s7Key, model.value);
}
}
}
#endregion
}