From c616fdcbd1b849976d0d2622cb9492de40628716 Mon Sep 17 00:00:00 2001 From: ccongli <1441652193@qq.com> Date: Thu, 31 Aug 2023 17:34:29 +0800 Subject: [PATCH] =?UTF-8?q?Data=E6=A8=A1=E5=9D=97=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E9=87=87=E9=9B=86=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD=E5=BC=80?= =?UTF-8?q?=E5=8F=91v2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../VOL.Core/EFDbContext/EFLoggerProvider.cs | 4 + vol-net6/VOL.Core/EFDbContext/VOLContext.cs | 11 +- .../IServices/modbus/IDataProcessing.cs | 23 ++ .../IServices/modbus/IModbusService.cs | 25 ++ .../data/Partial/Data_DeviceService.cs | 12 +- .../Services/modbus/DataProcessing.cs | 92 ++++++ .../Services/modbus/ModbusTcpService.cs | 102 ++++++ vol-net6/VOL.Data/VOL.Data.csproj | 6 +- .../Controllers/Data/DataCaptureController.cs | 170 +++++++++- .../Controllers/Data/Data_DeviceController.cs | 3 + .../Data/Partial/Data_DeviceController.cs | 1 + .../Controllers/System/Sys_LogController.cs | 1 + vol-net6/VOL.WebApi/Program.cs | 28 +- vol-net6/VOL.WebApi/Utils/CommonUtil.cs | 41 +++ vol-net6/VOL.WebApi/Utils/DataConvertUtil.cs | 305 ++++++++++++++++++ 15 files changed, 812 insertions(+), 12 deletions(-) create mode 100644 vol-net6/VOL.Data/IServices/modbus/IDataProcessing.cs create mode 100644 vol-net6/VOL.Data/IServices/modbus/IModbusService.cs create mode 100644 vol-net6/VOL.Data/Services/modbus/DataProcessing.cs create mode 100644 vol-net6/VOL.Data/Services/modbus/ModbusTcpService.cs create mode 100644 vol-net6/VOL.WebApi/Utils/CommonUtil.cs create mode 100644 vol-net6/VOL.WebApi/Utils/DataConvertUtil.cs diff --git a/vol-net6/VOL.Core/EFDbContext/EFLoggerProvider.cs b/vol-net6/VOL.Core/EFDbContext/EFLoggerProvider.cs index 123093d..fde2f37 100644 --- a/vol-net6/VOL.Core/EFDbContext/EFLoggerProvider.cs +++ b/vol-net6/VOL.Core/EFDbContext/EFLoggerProvider.cs @@ -26,7 +26,11 @@ namespace VOL.Core.EFDbContext && logLevel == LogLevel.Information) { var logContent = formatter(state, exception); + // TODO: 拿到日志内容想怎么玩就怎么玩吧 + Console.WriteLine(); + Console.ForegroundColor = ConsoleColor.Green; // 字体绿色 Console.WriteLine(logContent); + Console.ResetColor(); } } public IDisposable BeginScope(TState state) => null; diff --git a/vol-net6/VOL.Core/EFDbContext/VOLContext.cs b/vol-net6/VOL.Core/EFDbContext/VOLContext.cs index c863152..8c9175c 100644 --- a/vol-net6/VOL.Core/EFDbContext/VOLContext.cs +++ b/vol-net6/VOL.Core/EFDbContext/VOLContext.cs @@ -84,11 +84,14 @@ namespace VOL.Core.EFDbContext { optionsBuilder.UseSqlServer(connectionString); } - //默认禁用实体跟踪 + // 默认禁用实体跟踪(注释记录EFCore时) optionsBuilder = optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); - //var loggerFactory = new LoggerFactory(); - //loggerFactory.AddProvider(new EFLoggerProvider()); - // optionsBuilder.UseLoggerFactory(loggerFactory); + + // 记录EFCore产生的SQL语句 + var loggerFactory = new LoggerFactory(); + loggerFactory.AddProvider(new EFLoggerProvider()); + optionsBuilder.UseLoggerFactory(loggerFactory); + base.OnConfiguring(optionsBuilder); } protected override void OnModelCreating(ModelBuilder modelBuilder) diff --git a/vol-net6/VOL.Data/IServices/modbus/IDataProcessing.cs b/vol-net6/VOL.Data/IServices/modbus/IDataProcessing.cs new file mode 100644 index 0000000..52047b2 --- /dev/null +++ b/vol-net6/VOL.Data/IServices/modbus/IDataProcessing.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VOL.Entity.DomainModels; + +namespace VOL.Data.IServices.modbus +{ + public interface IDataProcessing + { + // 写设备运行数据 + bool saveDeviceData(Data_Device device, out string message); + + + // 写设备生产数据 + bool saveProduceData(Data_Produce produce, out string message); + + + // 写设备性能数据 + bool saveEfficiencyData(); + } +} diff --git a/vol-net6/VOL.Data/IServices/modbus/IModbusService.cs b/vol-net6/VOL.Data/IServices/modbus/IModbusService.cs new file mode 100644 index 0000000..c032f89 --- /dev/null +++ b/vol-net6/VOL.Data/IServices/modbus/IModbusService.cs @@ -0,0 +1,25 @@ +using NModbus; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace VOL.Data.IServices.modbus +{ + public interface IModbusService + { + /// + /// 创建主站客户端 + /// + /// + void createModbusClient(); + + + /// + /// 关闭链接 + /// + /// + void disConnent(); + } +} diff --git a/vol-net6/VOL.Data/Services/data/Partial/Data_DeviceService.cs b/vol-net6/VOL.Data/Services/data/Partial/Data_DeviceService.cs index 330cada..e6dc9ce 100644 --- a/vol-net6/VOL.Data/Services/data/Partial/Data_DeviceService.cs +++ b/vol-net6/VOL.Data/Services/data/Partial/Data_DeviceService.cs @@ -35,7 +35,15 @@ namespace VOL.Data.Services _httpContextAccessor = httpContextAccessor; _repository = dbRepository; //多租户会用到这init代码,其他情况可以不用 - //base.Init(dbRepository); + Init(dbRepository); } - } + + //重写ServiceBase Init方法,设置IsMultiTenancy=true开启多租户功能 + protected override void Init(IRepository repository) + { + //开启多租户功能,开启后会对查询、导出、删除、编辑功能同时生效 + //如果只需要对某个功能生效,如编辑,则在重写编辑方法中设置 IsMultiTenancy = true; + IsMultiTenancy = true; + } + } } diff --git a/vol-net6/VOL.Data/Services/modbus/DataProcessing.cs b/vol-net6/VOL.Data/Services/modbus/DataProcessing.cs new file mode 100644 index 0000000..a9d4f6c --- /dev/null +++ b/vol-net6/VOL.Data/Services/modbus/DataProcessing.cs @@ -0,0 +1,92 @@ +using Microsoft.AspNetCore.Http; +using VOL.Data.IServices.modbus; +using VOL.Entity.DomainModels; +using VOL.Core.Services; +using Microsoft.AspNetCore.Mvc; +using Autofac.Core; +using VOL.Core.Extensions.AutofacManager; + +namespace VOL.Data.Services.modbus +{ + public class DataProcessing : IDataProcessing, IDependency // 继承IDependency,交给Ioc容器接管 + { + private readonly IHttpContextAccessor _httpContextAccessor; + + public DataProcessing(IHttpContextAccessor httpContextAccessor) { + _httpContextAccessor = httpContextAccessor; + } + + // 写设备运行数据 + public bool saveDeviceData(Data_Device device, out string message) { + SaveModel model = new SaveModel(); + Dictionary mapData = new() + { + { "temperature", device.temperature ?? 68.0M }, + { "potential", device.potential ?? 220.0M }, + { "current", device.current ?? 24.0M }, + { "processno", device.processno ?? "10092768" }, + { "run_mode", device.run_mode ?? 1 } + }; + model.MainData = mapData; + try { + Core.Utilities.WebResponseContent result = Data_DeviceService.Instance.Add(model); + if (!result.Status) + { + message = result.Message; + //Logger.Info(result.Message); + return false; + } + } catch (Exception ex) + { + //Logger.Error(ex.Message); + message = ex.Message; + return false; + } + message = "ok"; + return true; + } + + + + // 写设备生产数据 + public bool saveProduceData(Data_Produce produce, out string message) + { + SaveModel model = new SaveModel(); + Dictionary mapData = new() + { + { "standby_time", produce.standby_time ?? 24 }, + { "run_time", produce.run_time ?? 20 }, + { "status", produce.status ?? 1 }, + { "turnout", produce.turnout ?? 1640 }, + { "turnout_one", produce.turnout_one ?? 450 }, + { "turnout_two", produce.turnout_two ?? 630 }, + { "turnout_three", produce.turnout_three ?? 560 } + }; + model.MainData = mapData; + try + { + Core.Utilities.WebResponseContent result = Data_ProduceService.Instance.Add(model); + if (!result.Status) + { + message = result.Message; + return false; + } + } + catch (Exception ex) + { + message = ex.Message; + return false; + } + message = "ok"; + return true; + } + + + // 写设备性能数据 + public bool saveEfficiencyData() + { + throw new NotImplementedException(); + } + + } +} diff --git a/vol-net6/VOL.Data/Services/modbus/ModbusTcpService.cs b/vol-net6/VOL.Data/Services/modbus/ModbusTcpService.cs new file mode 100644 index 0000000..1509b3d --- /dev/null +++ b/vol-net6/VOL.Data/Services/modbus/ModbusTcpService.cs @@ -0,0 +1,102 @@ +using NModbus; +using System.Net.Sockets; +using VOL.Data.IServices.modbus; + +namespace VOL.Data.Services.modbus +{ + public class ModbusTcpService : IModbusService + { + // IP + private string ip { set; get; } = "127.0.0.1"; + + // 端口 + private int port { set; get; } = 502; + + // 从站地址 + private int slaveNo { set; get; } = 1; + + private TcpClient client; + + private IModbusMaster modbusMaster; + + public ModbusTcpService(string ip, int port) { + this.ip = ip; + this.port = port; + this.client = new TcpClient(ip, port); + this.createModbusClient(); + } + + public void createModbusClient() + { + ModbusFactory modbusFactory = new(); + modbusMaster = modbusFactory.CreateMaster(client); + modbusMaster.Transport.ReadTimeout = 3000; //读超时 + modbusMaster.Transport.WriteTimeout = 3000;//写超时 + modbusMaster.Transport.Retries = 3; + modbusMaster.Transport.WaitToRetryMilliseconds = 500;//尝试重复连接间隔 + } + + + // 是否已连接 + public bool isConnected + { + get => client.Connected; + } + + // 读线圈 0x01 0x + public bool[] ReadCoils(byte slaveAddress, ushort startAddress, ushort num) + { + return modbusMaster.ReadCoils(slaveAddress, startAddress, num); + } + + // 读离散输入 0x02 1x + public bool[] ReadInputs(byte slaveAddress, ushort startAddress, ushort num) + { + return modbusMaster.ReadInputs(slaveAddress, startAddress, num); + } + + // 读保持寄存器 0x03 4x + public ushort[] ReadHoldingRegisters(byte slaveAddress, ushort startAddress, ushort num) + { + return modbusMaster.ReadHoldingRegisters(slaveAddress, startAddress, num); + } + + // 读输入寄存器 0x04 3x + public ushort[] ReadInputRegisters(byte slaveAddress, ushort startAddress, ushort num) + { + return modbusMaster.ReadInputRegisters(slaveAddress, startAddress, num); + } + + // 写单个线圈 0x05 + public void WriteSingleCoil(byte slaveAddress, ushort startAddress, bool value) + { + modbusMaster.WriteSingleCoil(slaveAddress, startAddress, value); + } + + + // 写单个保持寄存器 0x06 + public void WriteSingleRegister(byte slaveAddress, ushort startAddress, ushort value) + { + modbusMaster.WriteSingleRegister(slaveAddress, startAddress, value); + } + + // 写多个线圈 0x0F + public void WriteMultipleCoils(byte slaveAddress, ushort startAddress, bool[] value) + { + modbusMaster.WriteMultipleCoils(slaveAddress, startAddress, value); + } + + // 写多个保持寄存器 0x10 + public void WriteMultipleRegisters(byte slaveAddress, ushort startAddress, ushort[] value) + { + modbusMaster.WriteMultipleRegisters(slaveAddress, startAddress, value); + } + + + // 关闭Socket + public void disConnent() { + client.Close(); + modbusMaster.Dispose(); + } + } +} diff --git a/vol-net6/VOL.Data/VOL.Data.csproj b/vol-net6/VOL.Data/VOL.Data.csproj index 1a8c46c..9dad5eb 100644 --- a/vol-net6/VOL.Data/VOL.Data.csproj +++ b/vol-net6/VOL.Data/VOL.Data.csproj @@ -13,9 +13,11 @@ - - + + + + diff --git a/vol-net6/VOL.WebApi/Controllers/Data/DataCaptureController.cs b/vol-net6/VOL.WebApi/Controllers/Data/DataCaptureController.cs index 0ed452a..9180f0d 100644 --- a/vol-net6/VOL.WebApi/Controllers/Data/DataCaptureController.cs +++ b/vol-net6/VOL.WebApi/Controllers/Data/DataCaptureController.cs @@ -3,6 +3,18 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authorization; using System; using VOL.Core.Filters; +using VOL.Core.Controllers.Basic; +using VOL.Data.IServices.modbus; +using VOL.Data.IServices; +using VOL.Data.Services.modbus; +using Microsoft.Extensions.DependencyInjection; +using Newtonsoft.Json.Linq; +using static System.Reflection.Metadata.BlobBuilder; +using System.Linq; +using System.Collections.Generic; +using VOL.WebApi.Utils; +using VOL.Core.Services; +using VOL.Entity.DomainModels; namespace VOL.WebApi.Controllers.Data { @@ -13,17 +25,173 @@ namespace VOL.WebApi.Controllers.Data [AllowAnonymous] public class DataCaptureController : Controller { + private static ModbusTcpService _service; // 静态字段 + + private readonly IHttpContextAccessor _httpContextAccessor; + + private readonly IDataProcessing _dataService; // 业务处理 + + + [ActivatorUtilitiesConstructor] + public DataCaptureController( + //ModbusTcpService service, // ModbusTcpService为有参构造,暂时无法注入 + IDataProcessing dataService, + IHttpContextAccessor httpContextAccessor + ) + { + //_service = service; + _dataService = dataService; + _httpContextAccessor = httpContextAccessor; + } + + // 静态构造器 类实例化前调用,且只调用一次 + static DataCaptureController() + { + try + { + _service = new ModbusTcpService("127.0.0.1", 502); + Console.WriteLine("master modbus tcp created..."); + } + catch (Exception) + { + Console.WriteLine("master modbus tcp connect failed!"); + } + + } + /// - /// 测试采集接口 + /// 测试定时接口 /// /// IActionResult //[ApiTask] [HttpGet, HttpPost, Route("test")] public IActionResult Test() { + //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); return Content(DateTime.Now.ToString("yyyy-MM-dd HH:mm:sss")); + } + + + + /// + /// 测试采集接口 + /// + /// IActionResult + //[ApiTask] + [HttpGet, HttpPost, Route("getData")] + public IActionResult Collection() + { + Console.WriteLine(_service); + bool isConnected = _service == null ? false : _service.isConnected; + if (!isConnected) + { + try + { + _service.disConnent(); + _service = new ModbusTcpService("127.0.0.1", 502); + Console.WriteLine("master modbus tcp reconnect..."); + } + catch (Exception) + { + Console.WriteLine("master modbus tcp reconnect failed!"); + } + isConnected = _service == null ? false : _service.isConnected; + if (!isConnected) + { + return Content("master modbus connect failed!"); + } + } + try { + // 读Int16 + ushort[] us1 = _service.ReadHoldingRegisters(1, 9, 1); + short v = DataConvertUtil.GetShort(us1, 0); + Console.WriteLine("Short Data:" + v); + // 读Float + ushort[] us2 = _service.ReadHoldingRegisters(1, 1, 2); + float f = DataConvertUtil.GetReal(us2, 0); + Console.WriteLine("Real Data:" + f); + // 读Bool + ushort[] us3 = _service.ReadHoldingRegisters(1, 11, 1); + bool[] bs = DataConvertUtil.GetBools(us3,0,1); + Console.WriteLine("Bools Data:" + String.Join(",",bs)); + + // 写String + ushort[] src = new ushort[6]; + DataConvertUtil.SetString(src, 0, "你好世界"); // UTF8 1个中文字符 = 3Byte + _service.WriteMultipleRegisters(1, 30, src); + + // 读String + ushort[] target = _service.ReadHoldingRegisters(1, 30, 6); + string str = DataConvertUtil.GetString(target,0,6); + Console.WriteLine("String Data:" + str.ToString()); + } catch (Exception ex) { + Console.WriteLine(ex.Message); + _service.disConnent(); + return Content("read data error!"); + } + return Content("ok!"); + } + + + + + + [HttpGet, HttpPost, Route("readTest")] + public IActionResult Test01() + { + if (_service.isConnected) + { + //Console.WriteLine("=========read0x========="); + //bool[] data0x = _service.ReadCoils(1, 0, 5); // 0x + ////bool[] bools = { true, false }; + //Array.ForEach(data0x, Console.WriteLine); + //Console.WriteLine("=========read0x========="); + + //Console.WriteLine("=========read1x========="); + //bool[] data1x = _service.ReadInputs(1, 0, 5); + //Array.ForEach(data1x, Console.WriteLine); + //Console.WriteLine("=========read1x========="); + + Console.WriteLine("=========read4x========="); + ushort[] data4xs_int16 = _service.ReadHoldingRegisters(1, 8, 2); + short val = DataConvertUtil.GetShort(data4xs_int16, 1); + Console.WriteLine(val); + + 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); + //uint[] data3x = data3xs.Select(x => (uint)x).ToArray(); + //Array.ForEach(data3x, Console.WriteLine); + //Console.WriteLine("=========read3x========="); + _service.disConnent(); + //List data = new(); + //data.Add(data0x); + //data.Add(data1x); + //data.Add(data3x); + //data.Add(data4x); + return Content("read ok"); + } + else + { + return Content("Modbus 从站连接失败!"); + } } } diff --git a/vol-net6/VOL.WebApi/Controllers/Data/Data_DeviceController.cs b/vol-net6/VOL.WebApi/Controllers/Data/Data_DeviceController.cs index d6fd483..7f11ed8 100644 --- a/vol-net6/VOL.WebApi/Controllers/Data/Data_DeviceController.cs +++ b/vol-net6/VOL.WebApi/Controllers/Data/Data_DeviceController.cs @@ -6,6 +6,8 @@ using Microsoft.AspNetCore.Mvc; using VOL.Core.Controllers.Basic; using VOL.Entity.AttributeManager; using VOL.Data.IServices; +using System; + namespace VOL.Data.Controllers { [Route("api/Data_Device")] @@ -15,6 +17,7 @@ namespace VOL.Data.Controllers public Data_DeviceController(IData_DeviceService service) : base(service) { + // 类存在多个构造函数时,没有加ActivatorUtilitiesConstructor注解,不为指定的执行构造 } } } diff --git a/vol-net6/VOL.WebApi/Controllers/Data/Partial/Data_DeviceController.cs b/vol-net6/VOL.WebApi/Controllers/Data/Partial/Data_DeviceController.cs index 3c9513c..28fcbac 100644 --- a/vol-net6/VOL.WebApi/Controllers/Data/Partial/Data_DeviceController.cs +++ b/vol-net6/VOL.WebApi/Controllers/Data/Partial/Data_DeviceController.cs @@ -28,6 +28,7 @@ namespace VOL.Data.Controllers { _service = service; _httpContextAccessor = httpContextAccessor; + //Console.WriteLine("123456789"); } } } diff --git a/vol-net6/VOL.WebApi/Controllers/System/Sys_LogController.cs b/vol-net6/VOL.WebApi/Controllers/System/Sys_LogController.cs index 9e0eed6..0e8e9f5 100644 --- a/vol-net6/VOL.WebApi/Controllers/System/Sys_LogController.cs +++ b/vol-net6/VOL.WebApi/Controllers/System/Sys_LogController.cs @@ -17,6 +17,7 @@ namespace VOL.System.Controllers public Sys_LogController(ISys_LogService service) : base("System", "System", "Sys_Log", service) { + // 没有多个构造函数时,执行默认构造 } } } diff --git a/vol-net6/VOL.WebApi/Program.cs b/vol-net6/VOL.WebApi/Program.cs index 35ffea1..92d1b94 100644 --- a/vol-net6/VOL.WebApi/Program.cs +++ b/vol-net6/VOL.WebApi/Program.cs @@ -22,7 +22,7 @@ namespace VOL.WebApi AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true); //CreateHostBuilder(args).Build().Run(); var host = CreateHostBuilder(args).Build(); - #region kafkaϢ + #region kafka订阅消息111 //if (AppSetting.Kafka.UseConsumer) //{ // using var scope = host.Services.CreateScope(); @@ -30,9 +30,9 @@ namespace VOL.WebApi // testConsumer.Consume(res => // { // Console.WriteLine($"recieve:{DateTime.Now.ToLongTimeString()} value:{res.Message.Value}"); - // //̬ ݴ Ȳ + // //静态方法 数据处理 入库等操作 // bool bl = DataHandle.AlarmData(res.Message.Value); - // //ص践رִCommit + // //回调函数需返回便于执行Commit // return bl; // }, AppSetting.Kafka.Topics.TestTopic); //} @@ -40,6 +40,7 @@ namespace VOL.WebApi host.Run(); } + public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => @@ -53,5 +54,26 @@ namespace VOL.WebApi webBuilder.UseIIS(); webBuilder.UseStartup(); }).UseServiceProviderFactory(new AutofacServiceProviderFactory()); + + + //public static async Task Main(string[] args) + //{ + // // 创建一个定时器,每隔1秒触发一次 + // var timer = new Timer(async state => + // { + // // 在这里编写您的异步任务逻辑 + // await Task.Delay(1000); + // Console.WriteLine("异步定时任务执行"); + // }, null, TimeSpan.Zero, TimeSpan.FromSeconds(1)); + // TimeSpan.Zero 表示定时器立即开始执行,TimeSpan.FromSeconds(1) 表示每隔1秒触发一次定时任务。 + + // // 等待一段时间,观察异步定时任务的执行 + // await Task.Delay(5000); + + // // 停止定时器 + // timer.Dispose(); + + // Console.WriteLine("定时器已停止"); + //} } } diff --git a/vol-net6/VOL.WebApi/Utils/CommonUtil.cs b/vol-net6/VOL.WebApi/Utils/CommonUtil.cs new file mode 100644 index 0000000..eb7685c --- /dev/null +++ b/vol-net6/VOL.WebApi/Utils/CommonUtil.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; + +namespace VOL.WebApi.Utils +{ + public class CommonUtil + { + // 实体对象转Dictionary + + public static Dictionary ConvertToDictionary(T entity) + { + var dictionary = new Dictionary(); + 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(Dictionary 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; + } + } +} diff --git a/vol-net6/VOL.WebApi/Utils/DataConvertUtil.cs b/vol-net6/VOL.WebApi/Utils/DataConvertUtil.cs new file mode 100644 index 0000000..db9e1d8 --- /dev/null +++ b/vol-net6/VOL.WebApi/Utils/DataConvertUtil.cs @@ -0,0 +1,305 @@ +using System.Text; +using System; + +namespace VOL.WebApi.Utils +{ + public class DataConvertUtil + { + /// + /// 赋值string string => ushort[] + /// + /// + /// + /// + /// + public static void SetString(ushort[] src, int start, string value) + { + byte[] bytesTemp = Encoding.UTF8.GetBytes(value); + ushort[] dest = Bytes2Ushorts(bytesTemp); + dest.CopyTo(src, start); + } + + /// + /// 获取string ushort[] => string + /// + /// + /// + /// + /// string + 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' }); + return res; + } + + /// + /// 赋值Real float => ushort[] + /// + /// + /// + /// + public static void SetReal(ushort[] src, int start, float value) + { + byte[] bytes = BitConverter.GetBytes(value); + + ushort[] dest = Bytes2Ushorts(bytes); + + dest.CopyTo(src, start); + } + + /// + /// 获取float ushort[] => float + /// + /// + /// + /// float + 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,true); + Array.Reverse(bytesTemp); + // !!!BitConverter默认是小端转换,如果是大端字节顺序存放,需要先反序字节顺序 + float res = BitConverter.ToSingle(bytesTemp, 0); + return res; + } catch (Exception e) + { + return 0; + } + + } + + /// + /// 赋值Short short => ushort[] + /// + /// + /// + /// + public static void SetShort(ushort[] src, int start, short value) + { + byte[] bytes = BitConverter.GetBytes(value); + + ushort[] dest = Bytes2Ushorts(bytes); + + dest.CopyTo(src, start); + } + + /// + /// 获取short ushort[] => short + /// + /// + /// + /// short + 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; + } + + } + + /// + /// 赋值Short short => ushort[] + /// + /// + /// + /// + public static void SetInt(ushort[] src, int start, int value) + { + byte[] bytes = BitConverter.GetBytes(value); + + ushort[] dest = Bytes2Ushorts(bytes); + + dest.CopyTo(src, start); + } + + + /// + /// 获取short ushort[] => int + /// + /// + /// + /// short + 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 + Array.Reverse(temp); // 100 0 + byte[] bytesTemp = Ushorts2Bytes(temp); + int res = BitConverter.ToInt32(bytesTemp, 0); + return res; + } catch (Exception e) + { + return 0; + } + + } + + + /// + /// 获取short ushort[] => long + /// + /// + /// + /// short + 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]; // 0 0 0 100 + Array.Reverse(temp); // 100 0 0 0 + byte[] bytesTemp = Ushorts2Bytes(temp); + long res = BitConverter.ToInt64(bytesTemp, 0); + return res; + } catch (Exception e) + { + return 0; + } + + } + + + + /// + /// 获取bool数组 ushort[] => bool[] + /// + /// + /// + /// short + + 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; + } + } + +}