Data模块数据采集管理功能开发v3

dev-0829
ccongli 1 year ago
parent e57ac99570
commit e235811929

@ -0,0 +1,41 @@
using System.Collections.Generic;
namespace VOL.Core.Utils
{
public class CommonUtil
{
// 实体对象转Dictionary
public static Dictionary<string, object> ConvertToDictionary<T>(T entity)
{
var dictionary = new Dictionary<string, object>();
var properties = typeof(T).GetProperties();
foreach (var property in properties)
{
var key = property.Name;
var value = property.GetValue(entity);
dictionary.Add(key, value);
}
return dictionary;
}
// Dictionary转实体对象
public static T ConvertToObject<T>(Dictionary<string, object> dictionary) where T : new()
{
var obj = new T();
var properties = typeof(T).GetProperties();
foreach (var property in properties)
{
if (dictionary.TryGetValue(property.Name, out var value))
{
property.SetValue(obj, value);
}
}
return obj;
}
}
}

@ -0,0 +1,304 @@
using System.Text;
using System;
namespace VOL.Core.Utils
{
public class DataConvertUtil
{
/// <summary>
/// 赋值string string => ushort[]
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="value"></param>
/// <returns></returns>
public static void SetString(ushort[] src, int start, string value)
{
byte[] bytesTemp = Encoding.UTF8.GetBytes(value);
ushort[] dest = Bytes2Ushorts(bytesTemp);
dest.CopyTo(src, start);
}
/// <summary>
/// 获取string ushort[] => string
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="len"></param>
/// <returns>string</returns>
public static string GetString(ushort[] src, int start, int len)
{
ushort[] temp = new ushort[len];
for (int i = 0; i < len; i++)
{
temp[i] = src[i + start];
}
byte[] bytesTemp = Ushorts2Bytes(temp);
//string res = Encoding.UTF8.GetString(bytesTemp).Trim(new char[] { '\0' }); // 去除字符串左右端的指定内容
string res = Encoding.UTF8.GetString(bytesTemp).Trim();
return res;
}
/// <summary>
/// 赋值Real float => ushort[]
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="value"></param>
public static void SetReal(ushort[] src, int start, float value)
{
byte[] bytes = BitConverter.GetBytes(value);
ushort[] dest = Bytes2Ushorts(bytes);
dest.CopyTo(src, start);
}
/// <summary>
/// 获取float ushort[] => float
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns>float</returns>
public static float GetReal(ushort[] src, int start)
{
try
{
ushort[] temp = new ushort[2];
for (int i = 0; i < 2; i++)
{
temp[i] = src[i + start];
}
byte[] bytesTemp = Ushorts2Bytes(temp,false);
//Array.Reverse(bytesTemp);
// BitConverter默认是小端转换如果是大端字节顺序存放需要先反序字节顺序
float res = BitConverter.ToSingle(bytesTemp, 0);
return res;
} catch (Exception e)
{
return 0;
}
}
/// <summary>
/// 赋值Short short => ushort[]
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="value"></param>
public static void SetShort(ushort[] src, int start, short value)
{
byte[] bytes = BitConverter.GetBytes(value);
ushort[] dest = Bytes2Ushorts(bytes);
dest.CopyTo(src, start);
}
/// <summary>
/// 获取short ushort[] => short
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns>short</returns>
public static short GetShort(ushort[] src, int start)
{
try
{
ushort[] temp = new ushort[1];
temp[0] = src[start];
byte[] bytesTemp = Ushorts2Bytes(temp);
short res = BitConverter.ToInt16(bytesTemp, 0);
return res;
}
catch (Exception e)
{
return 0;
}
}
/// <summary>
/// 赋值Short short => ushort[]
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="value"></param>
public static void SetInt(ushort[] src, int start, int value)
{
byte[] bytes = BitConverter.GetBytes(value);
ushort[] dest = Bytes2Ushorts(bytes);
dest.CopyTo(src, start);
}
/// <summary>
/// 获取short ushort[] => int
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns>short</returns>
public static int GetInt(ushort[] src, int start)
{
try {
ushort[] temp = new ushort[2];
temp[0] = src[start];
temp[1] = src[start + 1]; // 0 100
byte[] bytesTemp = Ushorts2Bytes(temp);
int res = BitConverter.ToInt32(bytesTemp, 0);
return res;
} catch (Exception e)
{
return 0;
}
}
/// <summary>
/// 获取short ushort[] => long
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns>short</returns>
public static long GetLong(ushort[] src, int start)
{
try {
ushort[] temp = new ushort[4];
temp[0] = src[start];
temp[1] = src[start + 1];
temp[2] = src[start + 2];
temp[3] = src[start + 3];
byte[] bytesTemp = Ushorts2Bytes(temp);
long res = BitConverter.ToInt64(bytesTemp, 0);
return res;
} catch (Exception e)
{
return 0;
}
}
/// <summary>
/// 获取bool数组 ushort[] => bool[]
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns>short</returns>
public static bool[] GetBools(ushort[] src, int start, int num)
{
ushort[] temp = new ushort[num];
for (int i = start; i < start + num; i++)
{
temp[i] = src[i + start];
} // 0 1 0 1 0 0 0 0 默认小端模式
//Array.Reverse(temp); // 0 0 0 0 1 0 1 0
byte[] bytes = Ushorts2Bytes(temp);
bool[] res = Bytes2Bools(bytes);
return res;
}
// byte[] => bool[]
private static bool[] Bytes2Bools(byte[] b)
{
bool[] array = new bool[8 * b.Length];
for (int i = 0; i < b.Length; i++)
{
for (int j = 0; j < 8; j++)
{
array[i * 8 + j] = (b[i] & 1) == 1;//判定byte的最后一位是否为1若为1则是true否则是false
b[i] = (byte)(b[i] >> 1);//将byte右移一位
}
}
return array;
}
// bool[] => byte
private static byte Bools2Byte(bool[] array)
{
if (array != null && array.Length > 0)
{
byte b = 0;
for (int i = 0; i < 8; i++)
{
if (array[i])
{
byte nn = (byte)(1 << i);//左移一位相当于×2
b += nn;
}
}
return b;
}
return 0;
}
// byte[] => ushort[]
private static ushort[] Bytes2Ushorts(byte[] src, bool reverse = false)
{
int len = src.Length;
byte[] srcPlus = new byte[len + 1];
src.CopyTo(srcPlus, 0);
int count = len >> 1;
if (len % 2 != 0)
{
count += 1;
}
ushort[] dest = new ushort[count];
if (reverse)
{
for (int i = 0; i < count; i++)
{
dest[i] = (ushort)(srcPlus[i * 2] << 8 | srcPlus[2 * i + 1] & 0xff);
}
}
else
{
for (int i = 0; i < count; i++)
{
dest[i] = (ushort)(srcPlus[i * 2] & 0xff | srcPlus[2 * i + 1] << 8);
}
}
return dest;
}
// ushort[] => byte[]
private static byte[] Ushorts2Bytes(ushort[] src, bool reverse = false)
{
int count = src.Length;
byte[] dest = new byte[count << 1];
if (reverse) // 大端
{
for (int i = 0; i < count; i++)
{
dest[i * 2] = (byte)(src[i] >> 8);
dest[i * 2 + 1] = (byte)(src[i] >> 0);
}
}
else // 小端
{
for (int i = 0; i < count; i++)
{
dest[i * 2] = (byte)(src[i] >> 0);
dest[i * 2 + 1] = (byte)(src[i] >> 8);
}
}
return dest;
}
}
}

@ -21,5 +21,26 @@ namespace VOL.Data.IServices.modbus
/// </summary>
/// <returns></returns>
void disConnent();
/// <summary>
/// <param name="slaveAddress">从站地址</param>
/// <param name="startAddress">起始地址</param>
/// <param name="object">数据</param>
/// 写数据
/// </summary>
/// <returns></returns>
void writeData(byte slaveAddress, ushort startAddress, object data);
/// <summary>
/// <param name="slaveAddress">从站地址</param>
/// <param name="startAddress">起始地址</param>
/// <param name="units">寄存器单元地址数</param>
/// 读数据
/// </summary>
/// <returns>dynamic</returns>
dynamic readData(byte slaveAddress, ushort startAddress, string type, int units = 1);
}
}

@ -1,6 +1,10 @@
using NModbus;
using System.Net.Sockets;
using VOL.Data.IServices.modbus;
using VOL.Core.Utils;
using VOL.Core.Extensions;
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
namespace VOL.Data.Services.modbus
{
@ -43,6 +47,78 @@ namespace VOL.Data.Services.modbus
get => client.Connected;
}
// 写寄存器数据
public void writeData(byte slaveAddress, ushort startAddress, object data)
{
var type = data.GetType().Name.ToLower();
dynamic val ;
ushort[]? units; // 单元数
switch (type) {
case "int16":
val = data.ToShort();
units = new ushort[1];
DataConvertUtil.SetShort(units, 0, val);
break;
case "int32":
val = data.ToInt();
units = new ushort[2];
DataConvertUtil.SetInt(units, 0, val);
break;
case "single":
val = data.ToFloat();
units = new ushort[2];
DataConvertUtil.SetReal(units, 0, val);
break;
case "string":
val = data.ToString();
int length = (int) Math.Ceiling((double) val.Length / 2);
units = new ushort[length]; // 先不考虑中文字符,一个寄存器地址存放两个字符
DataConvertUtil.SetString(units, 0, val); // units 25690 25690
break;
default:
throw new ArgumentException("暂未实现写入此类型:"+ type);
}
if (units != null) {
this.WriteMultipleRegisters(slaveAddress, startAddress, units);
}
}
// 读寄存器数据
public dynamic readData(byte slaveAddress, ushort startAddress, string type, int units = 1)
{
type = type.ToLower();
ushort[]? source;
dynamic? data = null;
switch (type)
{
case "int16":
source = this.ReadHoldingRegisters(slaveAddress, startAddress, 1);
data = DataConvertUtil.GetShort(source, 0);
break;
case "int32":
source = this.ReadHoldingRegisters(slaveAddress, startAddress, 2);
data = DataConvertUtil.GetInt(source, 0);
break;
case "single":
source = this.ReadHoldingRegisters(slaveAddress, startAddress, 2);
data = DataConvertUtil.GetReal(source, 0);
break;
case "string":
//units = val.Length * 2; // 先不考虑中文字符
source = this.ReadHoldingRegisters(slaveAddress, startAddress, (ushort) units); // 25690 25690 0 0
data = DataConvertUtil.GetString(source, 0, units);
break;
default:
throw new ArgumentException("暂未实现读取此类型:" + type);
}
return data;
}
// 读线圈 0x01 0x
public bool[] ReadCoils(byte slaveAddress, ushort startAddress, ushort num)
{

@ -40,7 +40,7 @@ namespace VOL.WebApi.Controllers.Data
/// 采集西门子设备
/// </summary>
/// <returns>IActionResult</returns>
//[ApiTask]
[ApiTask]
[HttpGet, HttpPost, Route("gatherSiemens")]
public IActionResult Collection()
{

@ -8,6 +8,7 @@ using VOL.Data.Services.modbus;
using Microsoft.Extensions.DependencyInjection;
using VOL.WebApi.Utils;
using VOL.Entity.DomainModels;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
namespace VOL.WebApi.Controllers.Data
{
@ -42,7 +43,8 @@ namespace VOL.WebApi.Controllers.Data
{
try
{
_service = new ModbusTcpService("127.0.0.1", 502);
//_service = new ModbusTcpService("127.0.0.1", 502);
_service = new ModbusTcpService("192.168.0.99", 502);
Console.WriteLine("master modbus tcp created...");
}
catch (Exception)
@ -62,12 +64,18 @@ namespace VOL.WebApi.Controllers.Data
{
//Logger.Info("log info test...");
//Logger.Error("log info error...");
Data_Device data_Device = new Data_Device();
bool result = _dataService.saveDeviceData(data_Device, out string message);
Console.WriteLine(message);
Data_Produce data_Produce = new Data_Produce();
bool result2 = _dataService.saveProduceData(data_Produce, out string message1);
Console.WriteLine(message1);
//Data_Device data_Device = new Data_Device();
//bool result = _dataService.saveDeviceData(data_Device, out string message);
//Console.WriteLine(message);
//Data_Produce data_Produce = new Data_Produce();
//bool result2 = _dataService.saveProduceData(data_Produce, out string message1);
//Console.WriteLine(message1);
_service = new ModbusTcpService("192.168.0.99", 502);
_service.writeData(1,0,(short)1);
_service.writeData(1,0,1);
_service.writeData(1,0,1F);
_service.writeData(1,0,"1234");
return Content(DateTime.Now.ToString("yyyy-MM-dd HH:mm:sss"));
}
@ -139,6 +147,7 @@ namespace VOL.WebApi.Controllers.Data
[HttpGet, HttpPost, Route("readTest")]
public IActionResult Test01()
{
_service = new ModbusTcpService("192.168.0.99", 502);
if (_service.isConnected)
{
//Console.WriteLine("=========read0x=========");
@ -151,20 +160,54 @@ namespace VOL.WebApi.Controllers.Data
//bool[] data1x = _service.ReadInputs(1, 0, 5);
//Array.ForEach(data1x, Console.WriteLine);
//Console.WriteLine("=========read1x=========");
// 读取从0开始文档上地址从1开始的地址需要减1
Console.WriteLine("=========read4x=========");
ushort[] data4xs_int16 = _service.ReadHoldingRegisters(1, 8, 2);
short val = DataConvertUtil.GetShort(data4xs_int16, 1);
// int16
ushort[] src0 = new ushort[1];
DataConvertUtil.SetShort(src0, 0, 2);
_service.WriteMultipleRegisters(1, 6429, src0);
ushort[] data4xs_int16 = _service.ReadHoldingRegisters(1, 6429, 1); // 运行状态
short val = DataConvertUtil.GetShort(data4xs_int16, 0);
Console.WriteLine(val);
ushort[] data4xs_int32 = _service.ReadHoldingRegisters(1, 1, 2);
int vval = DataConvertUtil.GetInt(data4xs_int32, 0);
Console.WriteLine(vval);
// 写 float
ushort[] src1 = new ushort[2];
DataConvertUtil.SetReal(src1, 0, 3.14F);
_service.WriteMultipleRegisters(1, 1215, src1);
// 读 float
ushort[] data4xs_float = _service.ReadHoldingRegisters(1, 1215, 2); // 加工数
float fval = DataConvertUtil.GetReal(data4xs_float, 0);
Console.WriteLine(fval);
//// string
//ushort[] data_strlen = _service.ReadHoldingRegisters(1, 6689, 1);
//short strlen = DataConvertUtil.GetShort(data_strlen, 0);
//Console.WriteLine(strlen);
//// 6690程序号不可写, 为双引号 asill码为34
//ushort[] src2 = new ushort[6];
//DataConvertUtil.SetString(src1, 0, "123456");
//_service.WriteMultipleRegisters(1, 6691, src2);
//ushort[] data4xs_str = _service.ReadHoldingRegisters(1, 6690, 52); // 程序号
//string str = DataConvertUtil.GetString(data4xs_str, 0, 52);
//Console.WriteLine(str);
ushort[] data4xs_int64 = _service.ReadHoldingRegisters(1, 4, 4);
long vvval = DataConvertUtil.GetLong(data4xs_int64, 0);
Console.WriteLine(vvval);
Console.WriteLine("=========read4x=========");
//ushort[] data4xs_float = _service.ReadHoldingRegisters(1, 1200, 2); // 刀具长度补偿编号
//float fval = DataConvertUtil.GetReal(data4xs_float, 0);
//Console.WriteLine(fval);
//ushort[] data4xs_int32 = _service.ReadHoldingRegisters(1, 1, 2); // 电机温度
//int vval = DataConvertUtil.GetInt(data4xs_int32, 0);
//Console.WriteLine(vval);
//ushort[] data4xs_int64 = _service.ReadHoldingRegisters(1, 4, 4); // 运行模式
//long vvval = DataConvertUtil.GetLong(data4xs_int64, 0);
//Console.WriteLine(vvval);
//Console.WriteLine("=========read4x=========");
//Console.WriteLine("=========read3x=========");
//ushort[] data3xs = _service.ReadInputRegisters(1, 4, 2);
@ -186,5 +229,99 @@ namespace VOL.WebApi.Controllers.Data
}
}
[HttpGet, HttpPost, Route("unitTestSem")]
public IActionResult Test02()
{
Console.Write(5 / 2);
_service = new ModbusTcpService("192.168.0.99", 502);
if (_service.isConnected)
{
// 读取从0开始文档上地址从1开始的地址需要减1
Console.WriteLine("=========read4x=========");
// 写数据
_service.writeData(1, 6429, 1);
_service.writeData(1, 1173, 256);
_service.writeData(1, 1215, 6.28F);
_service.writeData(1, 6691, "Hello World!!");
// 读数据
short s = _service.readData(1, 6429, "int16");
int i = _service.readData(1, 1173, "int32");
float f = _service.readData(1, 1215, "single");
string str = _service.readData(1, 6690, "string", 52);
Console.WriteLine(s);
Console.WriteLine(i);
Console.WriteLine(f);
Console.WriteLine(str);
Console.WriteLine("=========read4x=========");
_service.disConnent();
return Content("read ok");
}
else
{
return Content("Modbus 从站连接失败!");
}
}
[HttpGet, HttpPost, Route("unitTestCnc")]
public IActionResult Test03()
{
_service = new ModbusTcpService("192.168.0.100", 502);
if (_service.isConnected)
{
// 读取从0开始文档上地址从1开始的地址需要减1
Console.WriteLine("=========read4x=========");
// 写数据
_service.writeData(1, 6424, 2);
_service.writeData(1, 1309, 65537);
_service.writeData(1, 1307, 5.68F);
_service.writeData(1, 6640, "hehe");
// 读数据
short s = _service.readData(1, 6424, "int16");
int i = _service.readData(1, 1309, "int32");
float f = _service.readData(1, 1307, "single");
string str = _service.readData(1, 6640, "string", 2); // 一个寄存器地址存放两个字符
Console.WriteLine(s);
Console.WriteLine(i);
Console.WriteLine(f);
Console.WriteLine(str);
Console.WriteLine("=========read4x=========");
_service.disConnent();
return Content("read ok");
}
else
{
return Content("Modbus 从站连接失败!");
}
}
}
}

@ -34,7 +34,8 @@ namespace VOL.WebApi.Utils
temp[i] = src[i + start];
}
byte[] bytesTemp = Ushorts2Bytes(temp);
string res = Encoding.UTF8.GetString(bytesTemp).Trim(new char[] { '\0' });
//string res = Encoding.UTF8.GetString(bytesTemp).Trim(new char[] { '\0' }); // 去除字符串左右端的指定内容
string res = Encoding.UTF8.GetString(bytesTemp).Trim();
return res;
}
@ -68,8 +69,8 @@ namespace VOL.WebApi.Utils
{
temp[i] = src[i + start];
}
byte[] bytesTemp = Ushorts2Bytes(temp,true);
Array.Reverse(bytesTemp);
byte[] bytesTemp = Ushorts2Bytes(temp,false);
//Array.Reverse(bytesTemp);
// BitConverter默认是小端转换如果是大端字节顺序存放需要先反序字节顺序
float res = BitConverter.ToSingle(bytesTemp, 0);
return res;
@ -172,7 +173,7 @@ namespace VOL.WebApi.Utils
temp[1] = src[start + 1];
temp[2] = src[start + 2];
temp[3] = src[start + 3]; // 0 0 0 100
Array.Reverse(temp); // 100 0 0 0
//Array.Reverse(temp); // 100 0 0 0
byte[] bytesTemp = Ushorts2Bytes(temp);
long res = BitConverter.ToInt64(bytesTemp, 0);
return res;

Loading…
Cancel
Save