using HH.WCS.Mobox3.SXJK.api;
|
using HH.WCS.Mobox3.SXJK.util;
|
using Newtonsoft.Json.Linq;
|
using S7.Net;
|
using S7.Net.Types;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
using System.Web.Services.Description;
|
|
namespace HH.WCS.Mobox3.SXJK.device {
|
|
/// <summary>
|
/// 西门子plc
|
/// </summary>
|
public class S7Helper {
|
private static bool debug = false;
|
private static S7.Net.Plc plc = null;
|
static S7Helper() {
|
Init();
|
}
|
public static Dictionary<string, Plc> plcDic = new Dictionary<string, Plc>();
|
private static void Init() {
|
//配置文件读取所有的plc进行初始化
|
try {
|
foreach (var item in Settings.lineDeviceInfos)
|
{
|
var plc = new Plc(CpuType.S71500, item.address, 0, 1);
|
Link(plc);
|
if (!plcDic.ContainsKey(item.deviceNo)) {
|
plcDic.Add(item.deviceNo, plc);
|
}
|
}
|
}
|
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<string, string> s7TestData = new Dictionary<string, string>();
|
public 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.Info($"plc{plc.IP}连接失败,err={ex.Message}");
|
//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
|
|
|
|
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
|
{
|
Link(plc);
|
LogHelper.Info($"plc {device}断开连接,尝试重新连接", "输送线");
|
}
|
}
|
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;
|
}
|
|
/// <summary>
|
/// 从指定的西门子PLC设备中读取整数数据。
|
/// </summary>
|
/// <param name="device">PLC设备的标识符或名称。</param>
|
/// <param name="db">要读取的数据块的编号。</param>
|
/// <param name="byteAddr">在数据块中的起始字节地址。--偏移量</param>
|
/// <param name="count">要读取的整数数量。-- 长度</param>
|
/// <returns>包含读取到的整数数据的数组。如果发生错误或未读取到数据,则返回null。</returns>
|
internal static int ReadDint(string device, int db, int byteAddr)
|
{
|
int result = 0;
|
try
|
{
|
if (debug)
|
{
|
var s7Key = $"Dint_{db}_{byteAddr}_{1}";
|
if (s7TestData.ContainsKey(s7Key))
|
{
|
string str = s7TestData[s7Key];
|
result = int.Parse(str);
|
Console.WriteLine($"读取plc {device}信息成功, addr={byteAddr} data={string.Join(",", result)}");
|
}
|
}
|
else
|
{
|
var plc = GetPlc(device);
|
if (plc != null)
|
{
|
if (plc.IsConnected)
|
{
|
result = (int)plc.Read(DataType.DataBlock, db, byteAddr, VarType.DInt, 1, 0);
|
Console.WriteLine($"读取plc {device}信息成功,ip={plc.IP} addr={byteAddr} data={string.Join(",", result)}");
|
LogHelper.Info($"读取plc {device}信息成功,ip={plc.IP} addr={byteAddr} data={string.Join(",", result)}", "输送线");
|
}
|
else
|
{
|
Link(plc);
|
LogHelper.Info($"plc {device}断开连接,尝试重新连接", "输送线");
|
}
|
}
|
else
|
{
|
Console.WriteLine($"plc {device}不存在");
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine($"ReadInt,device={device} addr={byteAddr} count={1} err={ex.Message}");
|
LogHelper.Error($"ReadInt,device={device} addr={byteAddr} count={1} err={ex.Message}", ex);
|
}
|
return result;
|
}
|
|
internal static float ReadReal(string device, int db, int byteAddr)
|
{
|
float result = 0;
|
try
|
{
|
if (debug)
|
{
|
var s7Key = $"Dint_{db}_{byteAddr}_{1}";
|
if (s7TestData.ContainsKey(s7Key))
|
{
|
string str = s7TestData[s7Key];
|
result = int.Parse(str);
|
Console.WriteLine($"读取plc {device}信息成功, addr={byteAddr} data={string.Join(",", result)}");
|
}
|
}
|
else
|
{
|
var plc = GetPlc(device);
|
if (plc != null)
|
{
|
if (plc.IsConnected)
|
{
|
result = (float)plc.Read(DataType.DataBlock, db, byteAddr, VarType.Real, 1, 0);
|
Console.WriteLine($"读取plc {device}信息成功,ip={plc.IP} addr={byteAddr} data={string.Join(",", result)}");
|
LogHelper.Info($"读取plc {device}信息成功,ip={plc.IP} addr={byteAddr} data={string.Join(",", result)}", "输送线");
|
}
|
else
|
{
|
Link(plc);
|
LogHelper.Info($"plc {device}断开连接,尝试重新连接", "输送线");
|
}
|
}
|
else
|
{
|
Console.WriteLine($"plc {device}不存在");
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine($"ReadInt,device={device} addr={byteAddr} count={1} err={ex.Message}");
|
LogHelper.Error($"ReadInt,device={device} addr={byteAddr} count={1} err={ex.Message}", ex);
|
}
|
return result;
|
}
|
|
/// <summary>
|
///
|
/// </summary>
|
/// <param name="db"></param>
|
/// <param name="byteAddr"></param>
|
/// <param name="data"></param>
|
/// <returns></returns>
|
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)}", "输送线");
|
result = readData == data;
|
}
|
}
|
}
|
catch (Exception ex) {
|
LogHelper.Error($"写入plc1信息失败,ip={plc.IP} addr={byteAddr} data={data} err={ex.Message}", ex);
|
}
|
return result;
|
}
|
|
/// <summary>
|
///
|
/// </summary>
|
/// <param name="device"></param>
|
/// <param name="db"></param>
|
/// <param name="byteAddr"></param>
|
/// <param name="data"></param>
|
/// <returns></returns>
|
internal static bool WriteInt(string device, int db, int byteAddr, short data)
|
{
|
var result = false;
|
try
|
{
|
var plc = GetPlc(device);
|
if (plc != null)
|
{
|
if (plc.IsConnected)
|
{
|
plc.Write(DataType.DataBlock, db, byteAddr, data);
|
Console.WriteLine($"写入plc信息,ip={plc.IP} addr={byteAddr} data={data} ");
|
LogHelper.Info($"写入plc {device}信息,ip={plc.IP} addr={byteAddr} data={data} ", "输送线");
|
|
//写完再读一次确认
|
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)}", "输送线");
|
result = readData == data;
|
}
|
else
|
{
|
Console.WriteLine("准备连接plc");
|
Link(plc);
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
LogHelper.Error($"写入plc1信息失败,ip={plc.IP} addr={byteAddr} data={data} err={ex.Message}", ex);
|
}
|
return result;
|
}
|
/// <summary>
|
///
|
/// </summary>
|
/// <param name="device"></param>
|
/// <param name="db"></param>
|
/// <param name="byteAddr"></param>
|
/// <param name="data"></param>
|
/// <returns></returns>
|
internal static bool WriteDint(string device, int db, int byteAddr, int data)
|
{
|
var result = false;
|
try
|
{
|
var plc = GetPlc(device);
|
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} ", "输送线");
|
|
//写完再读一次确认
|
var readData = (int)plc.Read(DataType.DataBlock, db, byteAddr, VarType.DInt, 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)}", "输送线");
|
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}不存在");
|
}
|
}
|
}
|
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}";
|
if (s7TestData.ContainsKey(s7Key)) {
|
var data = s7TestData[s7Key];
|
result = data;
|
Console.WriteLine($"ReadStr 成功, addr={byteAddr} res={result}");
|
}
|
}
|
else {
|
var plc = GetPlc(device);
|
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);
|
}
|
}
|
}
|
}
|
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 用于模拟测试
|
/// <summary>
|
/// short类型,一个占2个byte
|
/// </summary>
|
public class DBWModel {
|
public int db { get; set; }
|
public int byteAddr { get; set; }
|
/// <summary>
|
/// int类型需要用逗号分开,string不需要
|
/// </summary>
|
public string value { get; set; }
|
}
|
/// <summary>
|
/// 字符串类型,一个占1个byte
|
/// </summary>
|
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; }
|
/// <summary>
|
/// 1:true 0:false
|
/// </summary>
|
public int value { get; set; }
|
}
|
public static void s7SetInt(DBWModel model) {
|
var data = model.value.Split(',');
|
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}";
|
if (s7TestData.ContainsKey(s7Key)) {
|
s7TestData[s7Key] = model.value;
|
}
|
else {
|
s7TestData.Add(s7Key, model.value);
|
}
|
}
|
}
|
#endregion
|
}
|