You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lj_plc/Main/Mesnac.Basic/DataProcessor.cs

1686 lines
60 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.ComponentModel;
using System.Reflection;
using System.Windows.Forms;
namespace Mesnac.Basic
{
/// <summary>
/// 数据处理器
/// </summary>
public class DataProcessor
{
#region 获取浮点数值的有效小数位数
/// <summary>
/// 获取浮点数值的有效小数位数
/// </summary>
/// <param name="value">浮点数值</param>
/// <param name="maxPrecision">允许返回的最大小数位数</param>
/// <returns>返回有效小数位数</returns>
public static int GetValidPrecision(object value, int maxPrecision)
{
if (DataProcessor.IsNullOrEmpty(value))
{
return 0;
}
else
{
if (value.ToString().IndexOf(".") == -1)
{
return 0;
}
else
{
string strValue = value.ToString();
string precision = strValue.Substring(strValue.IndexOf(".") + 1);
int cnt = 0; //保存末尾0的个数
for (int i = precision.Length - 1; i > 0; i--)
{
if (precision.ToCharArray()[i] == '0')
{
cnt++;
}
else
{
break;
}
}
int result = precision.Length - cnt; //为有效小数位数
if (result > maxPrecision)
{
return maxPrecision;
}
else
{
return result;
}
}
}
}
#endregion
#region 对数据行字段取值方法
/// <summary>
/// 获取byte数据列的值
/// </summary>
/// <param name="dr"></param>
/// <param name="field"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static byte RowValue(DataRow dr, string field, byte defaultValue)
{
byte Result = defaultValue;
if (dr.Table.Columns.Contains(field))
{
if (dr[field] != null && dr[field] != DBNull.Value)
{
if (byte.TryParse(dr[field].ToString(), out Result))
{
return Result;
}
}
}
else
{
ICSharpCode.Core.LoggingService<DataProcessor>.Error("DataTable中不存在[" + field + "]列!");
}
return defaultValue;
}
/// <summary>
/// 获取Short数据列的值
/// </summary>
/// <param name="dr"></param>
/// <param name="field"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static short RowValue(DataRow dr, string field, short defaultValue)
{
short Result = defaultValue;
if (dr.Table.Columns.Contains(field))
{
if (dr[field] != null && dr[field] != DBNull.Value)
{
if (short.TryParse(dr[field].ToString(), out Result))
{
return Result;
}
}
}
else
{
ICSharpCode.Core.LoggingService<DataProcessor>.Error("DataTable中不存在[" + field + "]列!");
}
return defaultValue;
}
/// <summary>
/// 获取整型数据列的值
/// </summary>
/// <param name="dr"></param>
/// <param name="field"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static int RowValue(DataRow dr, string field, int defaultValue)
{
int Result = defaultValue;
if (dr.Table.Columns.Contains(field))
{
if (dr[field] != null && dr[field] != DBNull.Value)
{
if (int.TryParse(dr[field].ToString(), out Result))
{
return Result;
}
}
}
else
{
ICSharpCode.Core.LoggingService<DataProcessor>.Error("DataTable中不存在[" + field + "]列!");
}
return defaultValue;
}
/// <summary>
/// 获取float数据列的值
/// </summary>
/// <param name="dr"></param>
/// <param name="field"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static float RowValue(DataRow dr, string field, float defaultValue)
{
float Result = defaultValue;
if (dr.Table.Columns.Contains(field))
{
if (dr[field] != null && dr[field] != DBNull.Value)
{
if (float.TryParse(dr[field].ToString(), out Result))
{
return Result;
}
}
}
else
{
ICSharpCode.Core.LoggingService<DataProcessor>.Error("DataTable中不存在[" + field + "]列!");
}
return defaultValue;
}
/// <summary>
/// 获取double数据列的值
/// </summary>
/// <param name="dr"></param>
/// <param name="field"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static double RowValue(DataRow dr, string field, double defaultValue)
{
double Result = defaultValue;
if (dr.Table.Columns.Contains(field))
{
if (dr[field] != null && dr[field] != DBNull.Value)
{
if (double.TryParse(dr[field].ToString(), out Result))
{
return Result;
}
}
}
else
{
ICSharpCode.Core.LoggingService<DataProcessor>.Error("DataTable中不存在[" + field + "]列!");
}
return defaultValue;
}
/// <summary>
/// 获取decimal数据列的值
/// </summary>
/// <param name="dr"></param>
/// <param name="field"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static decimal RowValue(DataRow dr, string field, decimal defaultValue)
{
decimal Result = defaultValue;
if (dr.Table.Columns.Contains(field))
{
if (dr[field] != null && dr[field] != DBNull.Value)
{
if (decimal.TryParse(dr[field].ToString(), out Result))
{
return Result;
}
}
}
else
{
ICSharpCode.Core.LoggingService<DataProcessor>.Error("DataTable中不存在[" + field + "]列!");
}
return defaultValue;
}
/// <summary>
/// 获取DateTime数据列的值
/// </summary>
/// <param name="dr"></param>
/// <param name="field"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static DateTime RowValue(DataRow dr, string field, DateTime defaultValue)
{
DateTime Result = defaultValue;
if (dr.Table.Columns.Contains(field))
{
if (dr[field] != null && dr[field] != DBNull.Value)
{
if (DateTime.TryParse(dr[field].ToString(), out Result))
{
return Result;
}
}
}
else
{
ICSharpCode.Core.LoggingService<DataProcessor>.Error("DataTable中不存在[" + field + "]列!");
}
return defaultValue;
}
/// <summary>
/// 获取字符串数据列的值
/// </summary>
/// <param name="dr"></param>
/// <param name="field"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static string RowValue(DataRow dr, string field, string defaultValue)
{
if (dr.Table.Columns.Contains(field))
{
if (dr[field] != null && dr[field] != DBNull.Value)
{
return dr[field].ToString().Trim();
}
}
else
{
ICSharpCode.Core.LoggingService<DataProcessor>.Error("DataTable中不存在[" + field + "]列!");
}
return defaultValue;
}
#endregion
#region 获取数组的异或校验值
#region 获取数组的异或校验值(第1个元素与第2个元素异或结果与第3个元素异或直到最后一个元素)
/// <summary>
/// 获取数组的异或校验值(第1个元素与第2个元素异或结果与第3个元素异或指导最后一个元素)
/// </summary>
/// <param name="values">数组参数</param>
/// <returns>返回异或校验值</returns>
public static Int16 GetXorCheckValue(Int16[] values)
{
if (values == null || values.Length == 0)
{
return 0;
}
else if (values.Length == 1)
{
return values[0];
}
else
{
Int16 result = (Int16)(values[0] ^ values[1]);
for (int i = 2; i < values.Length; i++)
{
result = (Int16)(result ^ values[i]);
}
return result;
}
}
/// <summary>
/// 获取数组的异或校验值(第1个元素与第2个元素异或结果与第3个元素异或指导最后一个元素)
/// </summary>
/// <param name="values">数组参数</param>
/// <returns>返回异或校验值</returns>
public static object GetXorCheckValue(object[] values)
{
if (values == null || values.Length == 0)
{
return 0;
}
else if (values.Length == 1)
{
return values[0];
}
else
{
Int16 result = (Int16)(Convert.ToInt16(values[0]) ^ Convert.ToInt16(values[1]));
for (int i = 2; i < values.Length; i++)
{
result = (Int16)(Convert.ToInt16(result) ^ Convert.ToInt16(values[i]));
}
return result;
}
}
#endregion
#region 获取数组的异或校验值第一个参数与数组第一个元素异或结果与第2个元素异或直到最后一个元素
/// <summary>
/// 获取数组的异或校验值第一个参数与数组第一个元素异或结果与第2个元素异或直到最后一个元素
/// </summary>
/// <param name="param">起始参数</param>
/// <param name="values">数组元素</param>
/// <returns>返回异或校验值</returns>
public static Int16 GetXorCheckValueByParm(Int16 param, Int16[] values)
{
if (values == null || values.Length == 0)
{
return param;
}
else
{
Int16 result = param;
for (int i = 0; i < values.Length; i++)
{
result = (Int16)(result ^ values[i]);
}
return result;
}
}
/// <summary>
/// 获取数组的异或校验值第一个参数与数组第一个元素异或结果与第2个元素异或直到最后一个元素
/// </summary>
/// <param name="param">起始参数</param>
/// <param name="values">数组元素</param>
/// <returns>返回异或校验值</returns>
public static object GetXorCheckValueByParm(object param, object[] values)
{
if (values == null || values.Length == 0)
{
return param;
}
else
{
Int16 result = Convert.ToInt16(param);
for (int i = 0; i < values.Length; i++)
{
result = (Int16)(Convert.ToInt16(result) ^ Convert.ToInt16(values[i]));
}
return result;
}
}
#endregion
#endregion
#region 判断2个数组元素值是否相同
/// <summary>
/// 判断2个数组元素值是否相同
/// </summary>
/// <param name="arr1">数组1</param>
/// <param name="arr2">数组2</param>
/// <returns>相同返回true不同返回false</returns>
public static bool IsSameArrayValue(object[] arr1, object[] arr2)
{
if (arr1.Length != arr2.Length)
{
return false;
}
bool result = true;
for (int i = 0; i < arr1.Length; i++)
{
if (!arr1[i].Equals(arr2[i]))
{
result = false;
break;
}
}
return result;
}
#endregion
#region 克隆DataTable及数据的方法
/// <summary>
/// 克隆DataTable及数据的方法
/// </summary>
/// <param name="dt">要克隆的数据表</param>
/// <returns>返回克隆以后的数据表</returns>
public static DataTable Clone(DataTable dt)
{
DataTable dt2 = dt.Clone();
foreach (DataRow dr in dt.Rows)
{
DataRow dr2 = dt2.NewRow();
foreach (DataColumn dc in dt.Columns)
{
dr2[dc.ColumnName] = dr[dc.ColumnName];
}
dt2.Rows.Add(dr2);
}
return dt2;
}
#endregion
#region 从DataGridView控件获取DataTable数据
/// <summary>
/// 从DataGridView控件获取DataTable数据
/// </summary>
/// <param name="grid"></param>
/// <returns></returns>
public static DataTable GetDataTableFromGridView(DataGridView grid)
{
DataTable dt = grid.DataSource as DataTable;
if (dt != null)
{
DataTable table = dt.Clone();
foreach(DataGridViewRow dgvRow in grid.Rows)
{
DataRow row = table.NewRow();
foreach(DataGridViewColumn col in grid.Columns)
{
row[col.DataPropertyName] = dgvRow.Cells[col.Name].Value;
}
table.Rows.Add(row);
}
return table;
}
else
{
return null;
}
}
#endregion
#region 格式化小数位数
/// <summary>
/// 格式化小数位数
/// </summary>
/// <param name="floatValue">要格式化的小数对象</param>
/// <param name="maxPrecision">保留的最大小数位数</param>
/// <returns>返回格式化后的小数字符串值</returns>
public static object FormatFloatValue(object floatValue, int maxPrecision)
{
if (IsNullOrEmpty(floatValue))
{
return String.Empty;
}
else
{
int intPrecision = GetValidPrecision(floatValue, maxPrecision);
return String.Format("{0:f" + intPrecision + "}", floatValue);
}
}
#endregion
#region 格式化DataTable中小数位数
/// <summary>
/// 格式化DataTable
/// </summary>
/// <param name="dt">要格式化的DataTable对象</param>
/// <param name="noFormatColumns">排除在格式化之外的列</param>
/// <param name="maxPrecision">保留的最大小数位数</param>
/// <returns>返回格式化后的DataTable对象</returns>
public static DataTable FormatDataTable(DataTable dt, List<string> noFormatColumns, int maxPrecision)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
foreach (DataColumn dc in dt.Columns)
{
if (dc.DataType == typeof(double?) ||
dc.DataType == typeof(double) ||
dc.DataType == typeof(float?) ||
dc.DataType == typeof(float) ||
dc.DataType == typeof(decimal?) ||
dc.DataType == typeof(decimal) ||
dc.DataType == typeof(int?) ||
dc.DataType == typeof(int))
{
if (dt.Rows[i][dc] != null && dt.Rows[i][dc] != DBNull.Value)
{
if (noFormatColumns != null && noFormatColumns.Contains(dc.ColumnName))
{
continue;
}
double d = 0.0;
string ss = dt.Rows[i][dc].ToString();
if (double.TryParse(ss, out d) && d == 0)
{
dt.Rows[i][dc] = DBNull.Value;
}
else if (dc.DataType != typeof(int))
{
int intPrecision = GetValidPrecision(dt.Rows[i][dc], maxPrecision);
dt.Rows[i][dc] = String.Format("{0:f" + intPrecision + "}", dt.Rows[i][dc]);
}
}
}
}
}
return dt;
}
#endregion
#region 清除DataGridView中的选中行
/// <summary>
/// 清除DataGridView中的选中行
/// </summary>
/// <param name="grid"></param>
public static void ClearSelectedStatus(DataGridView grid)
{
if (grid != null && grid.Visible)
{
foreach (DataGridViewRow row in grid.Rows)
{
if (row.Selected)
{
row.Selected = false;
}
}
}
}
/// <summary>
/// 注册清除DataGridView中的选中行事件
/// </summary>
/// <param name="grid"></param>
public static void RegistClearSelectedEvent(DataGridView grid)
{
grid.VisibleChanged -= grid_VisibleChanged;
grid.VisibleChanged += grid_VisibleChanged;
grid.CellDoubleClick -= grid_CellDoubleClick;
grid.CellDoubleClick += grid_CellDoubleClick;
}
private static void grid_VisibleChanged(object sender, EventArgs e)
{
DataGridView grid = sender as DataGridView;
if (grid != null && grid.Visible)
{
foreach (DataGridViewRow row in grid.Rows)
{
if (row.Selected)
{
row.Selected = false;
}
}
}
}
private static void grid_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
DataGridView grid = sender as DataGridView;
if (grid != null && grid.Visible)
{
foreach (DataGridViewRow row in grid.Rows)
{
if (row.Selected)
{
row.Selected = false;
}
}
}
}
#endregion
#region "按字符串位数补0"
/// <summary>
/// 按字符串位数补0
/// </summary>
/// <param name="CharTxt">字符串</param>
/// <param name="CharLen">字符长度</param>
/// <returns></returns>
public static string FillZero(string CharTxt, int CharLen)
{
if (CharTxt.Length < CharLen)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < CharLen - CharTxt.Length; i++)
{
sb.Append("0");
}
sb.Append(CharTxt);
return sb.ToString();
}
else
{
return CharTxt;
}
}
#endregion
#region 判断字符串是否为纯数字
/// <summary>
/// 判断字符串是否为纯数字
/// </summary>
/// <param name="str">要判断的字符串</param>
/// <returns>是纯数字返回true否则返回false</returns>
public static bool IsNumeric(string str) //接收一个string类型的参数,保存到str里
{
if (str == null || str.Length == 0) //验证这个参数是否为空
return false; //是就返回False
ASCIIEncoding ascii = new ASCIIEncoding();//new ASCIIEncoding 的实例
byte[] bytestr = ascii.GetBytes(str); //把string类型的参数保存到数组里
foreach (byte c in bytestr) //遍历这个数组里的内容
{
if (c < 48 || c > 57) //判断是否为数字
{
return false; //不是就返回False
}
}
return true; //是就返回True
}
#endregion
#region 判断是否为空
/// <summary>
/// 判断是否为空
/// </summary>
/// <param name="value">要判断的对象</param>
/// <returns>为空返回true否则返回false</returns>
public static bool IsNullOrEmpty(object value)
{
if (value == null || value == DBNull.Value || string.IsNullOrWhiteSpace(value.ToString()))
{
return true;
}
return false;
}
#endregion
#region 合并消息列表
/// <summary>
/// 合并消息列表
/// </summary>
/// <param name="msgList">要合并的消息列表</param>
/// <returns>返回合并的消息字符串</returns>
public static string CombineMsgList(List<string> msgList)
{
if (msgList != null && msgList.Count > 0)
{
StringBuilder sb = new StringBuilder();
foreach (string msg in msgList)
{
sb.AppendLine(msg);
}
return sb.ToString();
}
return String.Empty;
}
/// <summary>
/// 合并消息列表
/// </summary>
/// <param name="msgList">要合并的消息列表</param>
/// <returns>返回合并的消息字符串</returns>
public static string CombineMsgList(List<string> msgList, string split)
{
if (msgList != null && msgList.Count > 0)
{
StringBuilder sb = new StringBuilder();
foreach (string msg in msgList)
{
if (String.IsNullOrEmpty(sb.ToString()))
{
sb.Append(msg);
}
else
{
sb.Append(split);
sb.Append(msg);
}
}
return sb.ToString();
}
return String.Empty;
}
#endregion
#region 把从PLC读取的buff数组转换为指定类型数据
#region 把Int16[]转换为Int32类型变量
#region 西门子PLC处理方法
/// <summary>
/// 把长度为2的Int16类型的数组转换为Int32类型的值
/// </summary>
/// <param name="buff">长度为2的Int16类型的数组</param>
/// <returns>返回Int32类型值</returns>
public static Int32 ToSiemensInt32(Int16[] buff)
{
if (buff == null)
{
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为Int32:失败原因buff为NULL!"));
return 0;
}
if (buff.Length != 2)
{
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为Int32:失败原因buff.Length={0}应为2!", buff.Length));
return 0;
}
Int16 int16Value0 = Convert.ToInt16(buff[0]);
Int16 int16Value1 = Convert.ToInt16(buff[1]);
byte[] byteValues0 = BitConverter.GetBytes(int16Value0);
byte[] byteValues1 = BitConverter.GetBytes(int16Value1);
byte[] resultValues = new byte[4];
resultValues[0] = byteValues1[0];
resultValues[1] = byteValues1[1];
resultValues[2] = byteValues0[0];
resultValues[3] = byteValues0[1];
Int32 result = BitConverter.ToInt32(resultValues, 0);
return result;
}
/// <summary>
/// 把长度为2的Int16类型的数组转换为Int32类型的值
/// </summary>
/// <param name="buff">长度为2的Int16类型的数组</param>
/// <returns>返回Int32类型值</returns>
public static Int32 ToSiemensInt32(int[] buff)
{
Int16[] buffResult = new Int16[buff.Length];
for (int i = 0; i < buff.Length; i++)
{
buffResult[i] = Convert.ToInt16(buff[i]);
}
return ToSiemensInt32(buffResult);
}
/// <summary>
/// 把2个Int16类型的数转换为Int32类型的值
/// </summary>
/// <param name="buff0">第一个Int16类型的参数</param>
/// <param name="buff1">第二个Int16类型的参数</param>
/// <returns>返回对应Int32类型的值</returns>
public static Int32 ToSiemensInt32(Int16 buff0, Int16 buff1)
{
Int16 int16Value0 = Convert.ToInt16(buff0);
Int16 int16Value1 = Convert.ToInt16(buff1);
byte[] byteValues0 = BitConverter.GetBytes(int16Value0);
byte[] byteValues1 = BitConverter.GetBytes(int16Value1);
byte[] resultValues = new byte[4];
resultValues[0] = byteValues1[0];
resultValues[1] = byteValues1[1];
resultValues[2] = byteValues0[0];
resultValues[3] = byteValues0[1];
Int32 result = BitConverter.ToInt32(resultValues, 0);
return result;
}
#endregion
#region 其他PLC处理方法
/// <summary>
/// 把长度为2的Int16类型的数组转换为Int32类型的值
/// </summary>
/// <param name="buff">长度为2的Int16类型的数组</param>
/// <returns>返回Int32类型值</returns>
public static Int32 ToInt32(Int16[] buff)
{
if (buff == null)
{
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为Int32:失败原因buff为NULL!"));
return 0;
}
if (buff.Length != 2)
{
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为Int32:失败原因buff.Length={0}应为2!", buff.Length));
return 0;
}
Int16 int16Value0 = Convert.ToInt16(buff[0]);
Int16 int16Value1 = Convert.ToInt16(buff[1]);
byte[] byteValues0 = BitConverter.GetBytes(int16Value0);
byte[] byteValues1 = BitConverter.GetBytes(int16Value1);
byte[] resultValues = new byte[4];
resultValues[0] = byteValues0[0];
resultValues[1] = byteValues0[1];
resultValues[2] = byteValues1[0];
resultValues[3] = byteValues1[1];
Int32 result = BitConverter.ToInt32(resultValues, 0);
return result;
}
/// <summary>
/// 把长度为2的Int16类型的数组转换为Int32类型的值
/// </summary>
/// <param name="buff">长度为2的Int16类型的数组</param>
/// <returns>返回Int32类型值</returns>
public static Int32 ToInt32(int[] buff)
{
Int16[] buffResult = new Int16[buff.Length];
for (int i = 0; i < buff.Length; i++)
{
buffResult[i] = Convert.ToInt16(buff[i]);
}
return ToInt32(buffResult);
}
/// <summary>
/// 把2个Int16类型的数转换为Int32类型的值
/// </summary>
/// <param name="buff0">第一个Int16类型的参数</param>
/// <param name="buff1">第二个Int16类型的参数</param>
/// <returns>返回对应Int32类型的值</returns>
public static Int32 ToInt32(Int16 buff0, Int16 buff1)
{
Int16 int16Value0 = Convert.ToInt16(buff0);
Int16 int16Value1 = Convert.ToInt16(buff1);
byte[] byteValues0 = BitConverter.GetBytes(int16Value0);
byte[] byteValues1 = BitConverter.GetBytes(int16Value1);
byte[] resultValues = new byte[4];
resultValues[0] = byteValues0[0];
resultValues[1] = byteValues0[1];
resultValues[2] = byteValues1[0];
resultValues[3] = byteValues1[1];
Int32 result = BitConverter.ToInt32(resultValues, 0);
return result;
}
#endregion
#endregion
#region 把Int16[]转换为float类型变量
#region 西门子PLC处理方法
/// <summary>
/// 把长度为2的Int16类型的数组转换为float类型的值
/// </summary>
/// <param name="buff">长度为2的Int16类型的数组</param>
/// <returns>返回float类型值</returns>
public static float ToSiemensFloat(Int16[] buff)
{
if (buff == null)
{
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为float类型失败原因buff为NULL!"));
return 0.0f;
}
if (buff.Length != 2)
{
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为float类型失败原因buff.Length={0}应为2!", buff.Length));
return 0.0f;
}
byte[] buff0Arr = BitConverter.GetBytes(buff[0]);
byte[] buff1Arr = BitConverter.GetBytes(buff[1]);
List<byte> lv = new List<byte>();
lv.Add(buff0Arr[1]);
lv.Add(buff0Arr[0]);
lv.Add(buff1Arr[1]);
lv.Add(buff1Arr[0]);
lv.Reverse();
float f = BitConverter.ToSingle(lv.ToArray<byte>(), 0);
return f;
}
/// <summary>
/// 把长度为2的Int16类型的数组转换为float类型的值
/// </summary>
/// <param name="buff">长度为2的Int16类型的数组</param>
/// <returns>返回float类型值</returns>
public static float ToSiemensFloat(int[] buff)
{
Int16[] buffResult = new Int16[buff.Length];
for (int i = 0; i < buff.Length; i++)
{
buffResult[i] = Convert.ToInt16(buff[i]);
}
return ToSiemensFloat(buffResult);
}
/// <summary>
/// 把2个Int16类型的整数转换为float类型的值
/// </summary>
/// <param name="buff0">第一个Int16类型参数</param>
/// <param name="buff1">第二个Int16类型参数</param>
/// <returns>返回对应float类型值</returns>
public static float ToSiemensFloat(Int16 buff0, Int16 buff1)
{
byte[] buff0Arr = BitConverter.GetBytes(buff0);
byte[] buff1Arr = BitConverter.GetBytes(buff1);
List<byte> lv = new List<byte>();
lv.Add(buff0Arr[1]);
lv.Add(buff0Arr[0]);
lv.Add(buff1Arr[1]);
lv.Add(buff1Arr[0]);
lv.Reverse();
float f = BitConverter.ToSingle(lv.ToArray<byte>(), 0);
return f;
}
#endregion
#region 其他PLC处理方法
/// <summary>
/// 把长度为2的Int16类型的数组转换为float类型的值
/// </summary>
/// <param name="buff">长度为2的Int16类型的数组</param>
/// <returns>返回float类型值</returns>
public static float ToFloat(Int16[] buff)
{
if (buff == null)
{
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为float类型失败原因buff为NULL!"));
return 0.0f;
}
if (buff.Length != 2)
{
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为float类型失败原因buff.Length={0}应为2!", buff.Length));
return 0.0f;
}
byte[] buff0Arr = BitConverter.GetBytes(buff[0]);
byte[] buff1Arr = BitConverter.GetBytes(buff[1]);
List<byte> lv = new List<byte>();
lv.Add(buff0Arr[0]);
lv.Add(buff0Arr[1]);
lv.Add(buff1Arr[0]);
lv.Add(buff1Arr[1]);
float f = BitConverter.ToSingle(lv.ToArray<byte>(), 0);
return f;
}
/// <summary>
/// 把长度为2的Int16类型的数组转换为float类型的值
/// </summary>
/// <param name="buff">长度为2的Int16类型的数组</param>
/// <returns>返回float类型值</returns>
public static float ToFloat(int[] buff)
{
Int16[] buffResult = new Int16[buff.Length];
for (int i = 0; i < buff.Length; i++)
{
buffResult[i] = Convert.ToInt16(buff[i]);
}
return ToFloat(buffResult);
}
/// <summary>
/// 把2个Int16类型的整数转换为float类型的值
/// </summary>
/// <param name="buff0">第一个Int16类型参数</param>
/// <param name="buff1">第二个Int16类型参数</param>
/// <returns>返回对应float类型值</returns>
public static float ToFloat(Int16 buff0, Int16 buff1)
{
byte[] buff0Arr = BitConverter.GetBytes(buff0);
byte[] buff1Arr = BitConverter.GetBytes(buff1);
List<byte> lv = new List<byte>();
lv.Add(buff0Arr[0]);
lv.Add(buff0Arr[1]);
lv.Add(buff1Arr[0]);
lv.Add(buff1Arr[1]);
float f = BitConverter.ToSingle(lv.ToArray<byte>(), 0);
return f;
}
#endregion
#endregion
#region 把Int16[]转换为string类型变量
/// <summary>
/// 把Int16[]类型的数组转换为字符串(跳过标识字符串长度的前2个字节)
/// </summary>
/// <param name="buff">Int16类型的数组参数</param>
/// <returns>返回转换后的字符串值</returns>
public static string ToString(Int16[] buff)
{
if (buff == null || buff.Length <= 2)
{
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为字符串失败原因buff为NULL!"));
return String.Empty;
}
List<byte> chars = new List<byte>();
for (int i = 0; i < buff.Length; i++) //跳过标识字符串长度的前2个字节
{
chars.AddRange(BitConverter.GetBytes(buff[i]));
}
string Result = string.Empty;
Result = System.Text.Encoding.Default.GetString(chars.ToArray());
Result = Result.Replace("\0", string.Empty);
return Result.Trim();
}
//public static string ToString(Int16[] buff)
//{
// if (buff == null || buff.Length <= 2)
// {
// ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为字符串失败原因buff为NULL!"));
// return String.Empty;
// }
// List<byte> chars = new List<byte>();
// for (int i = 2; i < buff.Length; i++) //跳过标识字符串长度的前2个字节
// {
// chars.AddRange(BitConverter.GetBytes(buff[i]));
// }
// string Result = string.Empty;
// Result = System.Text.Encoding.Default.GetString(chars.ToArray());
// Result = Result.Replace("\0", string.Empty);
// return Result.Trim();
//}
/// <summary>
/// 把Int16类型的数组转换为字符串(跳过标识字符串长度的前2个字节)
/// </summary>
/// <param name="buff">Int16类型的数组参数</param>
/// <returns>返回转换后的字符串值</returns>
public static string ToString1(Int16[] buff)
{
if (buff == null || buff.Length <= 2)
{
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为字符串失败原因buff为NULL!"));
return String.Empty;
}
List<byte> chars = new List<byte>();
for (int i = 0; i < buff.Length; i++) //跳过标识字符串长度的前2个字节
{
chars.AddRange(BitConverter.GetBytes(buff[i]));
}
string Result = string.Empty;
Result = System.Text.Encoding.Default.GetString(chars.ToArray());
Result = Result.Replace("\0", string.Empty);
return Result.Trim();
}
#endregion
#region 把Int32[]转换为string类型变量
/// <summary>
/// 把Int32类型的数组转换为字符串
/// </summary>
/// <param name="buff">Int32类型的数组参数</param>
/// <returns>返回转换后的字符串值</returns>
public static string ToString(int[] buff)
{
Int16[] buffResult = new Int16[buff.Length];
for (int i = 0; i < buff.Length; i++)
{
buffResult[i] = (short)buff[i];
}
return ToString(buffResult);
}
/// <summary>
/// 把Int32类型的数组转换为字符串
/// </summary>
/// <param name="buff">Int32类型的数组参数</param>
/// <returns>返回转换后的字符串值</returns>
public static string ToString1(int[] buff)
{
Int16[] buffResult = new Int16[buff.Length];
for (int i = 0; i < buff.Length; i++)
{
buffResult[i] = (short)buff[i];
}
return ToString1(buffResult);
}
#endregion
#region 把Int16[]转换为DateTime对象
/// <summary>
/// 把Int16类型的数组转换为DateTime对性爱那个
/// </summary>
/// <param name="buff">Int16类型的数组参数</param>
/// <returns>返回转换后的DateTime对象</returns>
public static DateTime ToDateTime(Int16[] buff)
{
if (buff == null)
{
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为DateTime失败原因buff为NULL!"));
return new DateTime(1900, 1, 1, 0, 0, 0);
}
if (buff.Length != 6)
{
ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为DateTime失败原因buff长度不等于6!"));
return new DateTime(1900, 1, 1, 0, 0, 0);
}
DateTime dateResult = DateTime.Now;
string strDate = String.Format("{0}-{1}-{2} {3}:{4}:{5}", buff[0], buff[1], buff[2], buff[3], buff[4], buff[5]);
if (!DateTime.TryParse(strDate, out dateResult))
{
dateResult = DateTime.Now;
//ICSharpCode.Core.LoggingService<DataProcessor>.Warn(String.Format("把PLC数据解析为DateTime失败!"));
}
return dateResult;
}
#endregion
#endregion
#region 把系统变量转换为要写入PLC的数据
#region 把Int32转换为PLC数据
#region 西门子PLC处理方法
/// <summary>
/// 把Int32类型的变量转换为Int16[]
/// </summary>
/// <param name="value">要转换的Int32类型变量</param>
/// <returns>返回转换后的Int16[]</returns>
public static Int16[] ToSiemensPLCInt16Array(Int32 value)
{
Int16[] buff = new Int16[2];
for (int i = 0; i < buff.Length; i++)
{
buff[i] = 0;
}
byte[] byteValues = BitConverter.GetBytes(value);
Int16[] intValues = new Int16[2];
intValues[0] = System.Convert.ToInt16(System.Convert.ToString(byteValues[3], 2).PadLeft(8, '0') + System.Convert.ToString(byteValues[2], 2).PadLeft(8, '0'), 2);
intValues[1] = System.Convert.ToInt16(System.Convert.ToString(byteValues[1], 2).PadLeft(8, '0') + System.Convert.ToString(byteValues[0], 2).PadLeft(8, '0'), 2);
buff[0] = intValues[0];
buff[1] = intValues[1];
return buff;
}
/// <summary>
/// 把Int32类型的变量转换为object[]
/// </summary>
/// <param name="value">要转换的Int32类型的变量</param>
/// <returns>返回转换后的object[]</returns>
public static object[] ToSiemensPLCDataArray(Int32 value)
{
Int16[] buff = ToSiemensPLCInt16Array(value);
object[] result = new object[buff.Length];
Array.Copy(buff, result, buff.Length);
return result;
}
#endregion
#region 其他PLC处理方法
/// <summary>
/// 把Int32类型的变量转换为Int16[]
/// </summary>
/// <param name="value">要转换的Int32类型变量</param>
/// <returns>返回转换后的Int16[]</returns>
public static Int16[] ToPLCInt16Array(Int32 value)
{
Int16[] buff = new Int16[2];
for (int i = 0; i < buff.Length; i++)
{
buff[i] = 0;
}
byte[] byteValues = BitConverter.GetBytes(value);
buff[0] = BitConverter.ToInt16(byteValues, 0);
buff[1] = BitConverter.ToInt16(byteValues, 2);
return buff;
}
/// <summary>
/// 把Int32类型的变量转换为object[]
/// </summary>
/// <param name="value">要转换的Int32类型的变量</param>
/// <returns>返回转换后的object[]</returns>
public static object[] ToPLCDataArray(Int32 value)
{
Int16[] buff = ToPLCInt16Array(value);
object[] result = new object[buff.Length];
Array.Copy(buff, result, buff.Length);
return result;
}
#endregion
#endregion
#region 把float转换为PLC数据
#region 西门子PLC处理方法
/// <summary>
/// 把float类型的变量转换为Int16[]
/// </summary>
/// <param name="fvalue">要转换的float类型的变量</param>
/// <returns>返回转换后的Int16[]</returns>
public static Int16[] ToSiemensPLCInt16Array(float fvalue)
{
byte[] byteValues = BitConverter.GetBytes(fvalue);
Int16[] intValues = new Int16[2];
intValues[0] = System.Convert.ToInt16(System.Convert.ToString(byteValues[3], 2).PadLeft(8, '0') + System.Convert.ToString(byteValues[2], 2).PadLeft(8, '0'), 2);
intValues[1] = System.Convert.ToInt16(System.Convert.ToString(byteValues[1], 2).PadLeft(8, '0') + System.Convert.ToString(byteValues[0], 2).PadLeft(8, '0'), 2);
return intValues;
}
/// <summary>
/// 把float类型的变量转换为object[]
/// </summary>
/// <param name="fvalue">要转换的float类型的变量</param>
/// <returns>返回转换后的object[]</returns>
public static object[] ToSiemensPLCDataArray(float fvalue)
{
Int16[] buff = ToSiemensPLCInt16Array(fvalue);
object[] buffResult = new object[buff.Length];
Array.Copy(buff, buffResult, buff.Length);
return buffResult;
}
#endregion
#region 其他PLC处理方法
/// <summary>
/// 把float类型的变量转换为Int16[]
/// </summary>
/// <param name="fvalue">要转换的float类型的变量</param>
/// <returns>返回转换后的Int16[]</returns>
public static Int16[] ToPLCInt16Array(float fvalue)
{
byte[] byteValues = BitConverter.GetBytes(fvalue);
Int16[] intValues = new Int16[2];
intValues[0] = BitConverter.ToInt16(byteValues, 0);
intValues[1] = BitConverter.ToInt16(byteValues, 2);
return intValues;
}
/// <summary>
/// 把float类型的变量转换为object[]
/// </summary>
/// <param name="fvalue">要转换的float类型的变量</param>
/// <returns>返回转换后的object[]</returns>
public static object[] ToPLCDataArray(float fvalue)
{
Int16[] buff = ToPLCInt16Array(fvalue);
object[] buffResult = new object[buff.Length];
Array.Copy(buff, buffResult, buff.Length);
return buffResult;
}
#endregion
#endregion
#region 把String转换为PLC数据
/// <summary>
/// 把字符串变量转换为Int16[]
/// </summary>
/// <param name="str">要转换的字符串变量</param>
/// <returns>返回转换后的Int16[]</returns>
public static Int16[] ToPLCInt16Array(string str)
{
byte[] temp = System.Text.Encoding.Default.GetBytes(str);
Int32 charLen = temp.Length;
object[] lenBuff = ToSiemensPLCDataArray(charLen);
Int16[] buff = new Int16[temp.Length / 2 + temp.Length % 2];
if (temp.Length % 2 == 0)
{
for (int i = 0; i < buff.Length; i++)
{
buff[i] = BitConverter.ToInt16(temp, i * 2);
}
}
else
{
byte[] temp1 = new byte[temp.Length + 1];
Array.Copy(temp, temp1, temp.Length);
for (int i = 0; i < buff.Length; i++)
{
buff[i] = BitConverter.ToInt16(temp1, i * 2);
}
}
//cfm20210804修改
//Int16[] buffResult = new Int16[buff.Length + lenBuff.Length];
//Array.Copy(lenBuff, buffResult, lenBuff.Length); //预留2个字节的位置保存字符串的实际长度
//Array.Copy(buff, 0, buffResult, lenBuff.Length, buff.Length);
//return buffResult;
return buff;
}
/// <summary>
/// 把字符串变量转换为object[]
/// </summary>
/// <param name="str">要转换的字符串变量</param>
/// <returns>返回转换后的object[]</returns>
public static object[] ToPLCDataArray(string str)
{
Int16[] buff = ToPLCInt16Array(str);
object[] buffResult = new object[buff.Length];
Array.Copy(buff, buffResult, buff.Length);
return buffResult;
}
/// <summary>
/// 把字符串变量转换为Int16[]
/// </summary>
/// <param name="str">要转换的字符串变量</param>
/// <param name="length">要补够的长度</param>
/// <returns>返回转换后的Int16[]</returns>
public static object[] ToPLCDataArray(string str, int length)
{
object[] buff = ToPLCDataArray(str);
#region 补够长度
object[] buffResult = new object[length];
for (int i = 0; i < buffResult.Length; i++)
{
buffResult[i] = 0;
}
Array.Copy(buff, buffResult, buff.Length);
#endregion
return buffResult;
}
#endregion
#region 把DateTime转换为PLC数据
/// <summary>
/// 把日期时间对象转换为Int16[]
/// </summary>
/// <param name="dtNow">要转换的日期时间对象</param>
/// <returns>返回转换后的Int16[]</returns>
public static Int16[] ToPLCInt16Array(DateTime dtNow)
{
Int16[] buff = new Int16[] { (short)dtNow.Year, (short)dtNow.Month, (short)dtNow.Day, (short)dtNow.Hour, (short)dtNow.Minute, (short)dtNow.Second };
return buff;
}
/// <summary>
/// 把日期时间对象转换为object[]
/// </summary>
/// <param name="dtNow">要转换的日期时间对象</param>
/// <returns>返回转换后的object[]</returns>
public static object[] ToPLCDataArray(DateTime dtNow)
{
Int16[] buff = ToPLCInt16Array(dtNow);
object[] buffResult = new object[buff.Length];
Array.Copy(buff, buffResult, buff.Length);
return buffResult;
}
#endregion
#region 把Time字符串转换为PLC数据
/// <summary>
/// 把Time字符串对象转换为Int16[]
/// </summary>
/// <param name="timeStr">要转换的日期时间对象</param>
/// <returns>返回转换后的Int16[]</returns>
public static Int16[] ToPLCInt16ArrayFromTimeStr(string timeStr)
{
Int16[] buff = new Int16[] { 0, 0, 0 };
string[] times = timeStr.Split(new char[] { ':' });
if (times.Length != 3)
{
ICSharpCode.Core.LoggingService<DataProcessor>.Error("把Time字符串转为Int[]失败,格式不正确,请确保时间是以':'分隔的时、分、秒构成!");
return buff;
}
else
{
Int16.TryParse(times[0], out buff[0]);
Int16.TryParse(times[1], out buff[1]);
Int16.TryParse(times[2], out buff[2]);
return buff;
}
}
/// <summary>
/// 把Time字符串对象转换为object[]
/// </summary>
/// <param name="timeStr">要转换的Time字符串对象</param>
/// <returns>返回转换后的object[]</returns>
public static object[] ToPLCDataArrayFromTimeStr(string timeStr)
{
Int16[] buff = ToPLCInt16ArrayFromTimeStr(timeStr);
object[] buffResult = new object[buff.Length];
Array.Copy(buff, buffResult, buff.Length);
return buffResult;
}
#endregion
#endregion
#region 类型转换
/// <summary>
/// 将一个对象转换为指定类型
/// </summary>
/// <param name="obj">待转换的对象</param>
/// <param name="type">目标类型</param>
/// <returns>转换后的对象</returns>
public static object ChangeType(object obj, Type type)
{
if (type == null) return obj;
if (obj == null) return type.IsValueType ? Activator.CreateInstance(type) : null;
Type underlyingType = Nullable.GetUnderlyingType(type);
if (type.IsAssignableFrom(obj.GetType())) // 如果待转换对象的类型与目标类型兼容,则无需转换
{
return obj;
}
else if ((underlyingType ?? type).IsEnum) // 如果待转换的对象的基类型为枚举
{
if (underlyingType != null && string.IsNullOrEmpty(obj.ToString())) // 如果目标类型为可空枚举并且待转换对象为null 则直接返回null值
{
return null;
}
else
{
return Enum.Parse(underlyingType ?? type, obj.ToString());
}
}
else if (typeof(IConvertible).IsAssignableFrom(underlyingType ?? type)) // 如果目标类型的基类型实现了IConvertible则直接转换
{
try
{
return Convert.ChangeType(obj, underlyingType ?? type, null);
}
catch
{
return underlyingType == null ? Activator.CreateInstance(type) : null;
}
}
else
{
TypeConverter converter = TypeDescriptor.GetConverter(type);
if (converter.CanConvertFrom(obj.GetType()))
{
return converter.ConvertFrom(obj);
}
ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);
if (constructor != null)
{
object o = constructor.Invoke(null);
PropertyInfo[] propertys = type.GetProperties();
Type oldType = obj.GetType();
foreach (PropertyInfo property in propertys)
{
PropertyInfo p = oldType.GetProperty(property.Name);
if (property.CanWrite && p != null && p.CanRead)
{
property.SetValue(o, ChangeType(p.GetValue(obj, null), property.PropertyType), null);
}
}
return o;
}
}
return obj;
}
#endregion
#region 二进制操作方法
#region 二进制位操作
/// <summary>
/// 对Int16数据的指定起始位指定长度的二进制位赋值
/// </summary>
/// <param name="x">源Int16数据</param>
/// <param name="startIndex">二进制起始位从0开始低位->高位)</param>
/// <param name="length">要操作的长度</param>
/// <param name="value">要写入的值</param>
/// <returns>返回二进制操作后的数据</returns>
public static Int16 SetBitValue(Int16 x, int startIndex, int length, Int16 value)
{
int totalLen = 16;
string original = FillZero(Convert.ToString(x, 2), totalLen);
if (Convert.ToString(value, 2).Length > length)
{
string msg = "对数据的二进制操作失败,要写入的值超过了要操作的二进制长度!";
ICSharpCode.Core.LoggingService<DataProcessor>.Error(msg);
throw new Exception();
}
string param = FillZero(Convert.ToString(value, 2), length);
string result = original.Substring(0, totalLen - (startIndex + length)) + param + original.Substring(totalLen - startIndex);
return Convert.ToInt16(result, 2);
}
/// <summary>
/// 对object数据的指定起始位指定长度的二进制位赋值
/// </summary>
/// <param name="x">源object数据</param>
/// <param name="startIndex">二进制起始位从0开始低位->高位)</param>
/// <param name="length">要操作的长度</param>
/// <param name="value">要写入的值</param>
/// <returns>返回二进制操作后的数据</returns>
public static object SetBitValue(object x, int startIndex, int length, object value)
{
Int16 intX = Convert.ToInt16(x);
Int16 intValue = Convert.ToInt16(value);
return SetBitValue(intX, startIndex, length, intValue);
}
/// <summary>
/// 对Int32数据的指定起始位指定长度的二进制位赋值
/// </summary>
/// <param name="x">源Int32数据</param>
/// <param name="startIndex">二进制起始位从0开始低位->高位)</param>
/// <param name="length">要操作的长度</param>
/// <param name="value">要写入的值</param>
/// <returns>返回二进制操作后的数据</returns>
public static Int32 SetBitValue32(Int32 x, int startIndex, int length, Int32 value)
{
int totalLen = 32;
string original = FillZero(Convert.ToString(x, 2), totalLen);
if (Convert.ToString(value, 2).Length > length)
{
string msg = "对数据的二进制操作失败,要写入的值超过了要操作的二进制长度!";
ICSharpCode.Core.LoggingService<DataProcessor>.Error(msg);
throw new Exception();
}
string param = FillZero(Convert.ToString(value, 2), length);
string result = original.Substring(0, totalLen - (startIndex + length)) + param + original.Substring(totalLen - startIndex);
return Convert.ToInt32(result, 2);
}
/// <summary>
/// 对object数据的指定起始位指定长度的二进制位赋值
/// </summary>
/// <param name="x">源object数据</param>
/// <param name="startIndex">二进制起始位从0开始低位->高位)</param>
/// <param name="length">要操作的长度</param>
/// <param name="value">要写入的值</param>
/// <returns>返回二进制操作后的数据</returns>
public static object SetBitValue32(object x, int startIndex, int length, object value)
{
Int32 intX = Convert.ToInt32(x);
Int32 intValue = Convert.ToInt32(value);
return SetBitValue32(intX, startIndex, length, intValue);
}
#endregion
#region 二进制位操作辅助方法
/// <summary>
/// 高8位低8位转换byte[0]byte[1]->byte[1]byte[0]
/// </summary>
/// <param name="a">要进行高低位转换的Int16类型变量</param>
/// <returns>返回转换后的值</returns>
public static Int16 Swap(Int16 a)
{
byte[] orignalData = BitConverter.GetBytes(a);
List<byte> lst = new List<byte>();
for (int i = 0; i < orignalData.Length; i++)
{
lst.Add(orignalData[i]);
}
lst.Reverse();
Int16 newData = BitConverter.ToInt16(lst.ToArray(), 0);
return newData;
}
/// <summary>
/// 高低位转换byte[0]byte[1]byte[2]byte[3]->byte[3]byte[2]byte[1]byte[0]
/// </summary>
/// <param name="a">要进行高低位转换的Int32类型变量</param>
/// <returns>返回转换后的值</returns>
public static int Swap(int a)
{
byte[] orignalData = BitConverter.GetBytes(a);
List<byte> lst = new List<byte>();
for (int i = 0; i < orignalData.Length; i++)
{
lst.Add(orignalData[i]);
}
lst.Reverse();
int newData = BitConverter.ToInt32(lst.ToArray(), 0);
return newData;
}
#endregion
#region 解析二进制位
/// <summary>
/// 解析二进制位
/// </summary>
/// <param name="x">要解析的变量</param>
/// <param name="len">解析的长度</param>
/// <returns>返回解析的二进制值数组</returns>
public static int[] ParseBinaryValue(int x, int len)
{
int[] result = new int[len];
int b = 1;
for (int i = 0; i < len; i++)
{
result[i] = (x & b) == 0 ? 0 : 1;
b = b << 1;
}
return result;
}
#endregion
#endregion
}
}