change -长连接采集

master
启龙 曹 4 weeks ago
parent 801086a215
commit 59eaa8bc33

@ -29,6 +29,7 @@ using Sln.Imm.Daemon.Model.dao;
using Sln.Imm.Daemon.Model.dto;
using Sln.Imm.Daemon.Opc;
using Sln.Imm.Daemon.Opc.Impl;
using Sln.Imm.Daemon.Repository.service.@base;
using Sln.Imm.Daemon.Serilog;
namespace Sln.Imm.Daemon.Business;
@ -37,51 +38,82 @@ public class DeviceCollectionBusiness
{
private readonly SerilogHelper _serilog;
private readonly BaseDeviceInfoCacheService _cacheService;
private readonly BaseDeviceInfoCacheService _cacheService;
private readonly IOpcService _opcUaService;
private readonly List<IOpcService> _opcs;
public DeviceCollectionBusiness(SerilogHelper serilogHelper, BaseDeviceInfoCacheService cacheService,OpcUaService opcUaService)
private readonly IBaseService<BaseDeviceParamVal> _paramValService;
public DeviceCollectionBusiness(SerilogHelper serilogHelper, BaseDeviceInfoCacheService cacheService, List<IOpcService> opcs, IBaseService<BaseDeviceParamVal> paramValService)
{
_serilog = serilogHelper;
_cacheService = cacheService;
_opcUaService = opcUaService;
_opcs = opcs;
_paramValService = paramValService;
this.Handle();
//this.Handle();
}
public async Task Handle()
public async Task Handle2()
{
bool isFalg = true;
var deviceInfos = await _cacheService.GetValueAsync("BaseDeviceInfoCache");
_opcs.
}
public async Task Handle(IOpcService opcUa)
{
bool isFalg = true;
var deviceInfos = await _cacheService.GetValueAsync("BaseDeviceInfoCache");
int i = 0;
do
{
lock (string.Empty)
i++;
foreach (var item in deviceInfos)
{
foreach (var item in deviceInfos)
//bool result = await _opcUaService.ConnectAsync(item.networkAddress);
//if (!result)
//{
// throw new ArgumentNullException($"设备未连接");
//}
//Task.Run(async () =>
//{
// //_opcUaService.DisconnectAsync();
//});
try
{
Task.Run(async () =>
{
try
{
_serilog.Info($"开始采集{item.deviceName},设备数据");
var opcItemValues = await this.ReadParam(item);
_serilog.Info($"开始采集{item.deviceName},设备数据,第{i}次");
var opcItemValues = await this.ReadParam(item, opcUa);
this.SaveParam(item, opcItemValues, out List<DeviceParamValueDto> paramValues);
//this.SaveParam(item, opcItemValues, out List<DeviceParamValueDto> paramValues);
_serilog.Info($"{item.deviceName}数据采集完成:{JsonConvert.SerializeObject(opcItemValues)}");
_serilog.Info($"{item.deviceName}数据采集完成:{JsonConvert.SerializeObject(paramValues)}");
}
catch (Exception e)
{
_serilog.Info($"{item.deviceName}数据读取异常:{e.Message}");
}
});
}
Task.Delay(1000 * 1).Wait();
catch (Exception e)
{
_serilog.Info($"{item.deviceName}数据读取异常:{e.Message}");
}
}
if (i == 1000)
{
isFalg = false;
await opcUa.DisconnectAsync();
_serilog.Info($"读取完成断开连接");
}
await Task.Delay(1000 * 1);
} while (isFalg);
}
@ -89,7 +121,7 @@ public class DeviceCollectionBusiness
/// 读取设备参数
/// </summary>
/// <param name="device"></param>
public async Task<List<OpcNode>> ReadParam(BaseDeviceInfo device)
public async Task<List<OpcNode>> ReadParam(BaseDeviceInfo device,IOpcService opcUa)
{
try
{
@ -100,19 +132,19 @@ public class DeviceCollectionBusiness
List<string> deviceParams = device.deviceParams.Select(x => x.paramAddr).ToList();
bool result = await _opcUaService.ConnectAsync(device.networkAddress);
//bool result = await _opcUaService.ConnectAsync(device.networkAddress);
if (!result)
{
throw new ArgumentNullException($"设备未连接");
//if (!result)
//{
// throw new ArgumentNullException($"设备未连接");
}
//}
List<OpcNode> infos = await _opcUaService.ReadNodeAsync(deviceParams);
List<OpcNode> infos = await opcUa.ReadNodeAsync(deviceParams);
//var infos = _opcService.BrowseNodesAsync("ns=2;s=Devices/分厂一/车间一/测试空设备");
await _opcUaService.DisconnectAsync();
//await _opcUaService.DisconnectAsync();
return infos;
@ -124,35 +156,73 @@ public class DeviceCollectionBusiness
}
/// <summary>
///
/// 保存设备参数值到数据库
/// </summary>
/// <param name="device"></param>
/// <param name="opcItemValue"></param>
/// <param name="device">设备信息</param>
/// <param name="opcItemValues">OPC节点值列表</param>
/// <param name="paramValues">输出参数值DTO列表</param>
public void SaveParam(BaseDeviceInfo device, List<OpcNode> opcItemValues,
out List<DeviceParamValueDto> paramValues)
{
var deviceParams = device.deviceParams.ToList();
var now = DateTime.Now;
paramValues = deviceParams
.GroupJoin(opcItemValues,
param => param.paramAddr,
value => value.NodeId,
(param, values) => new { Param = param, Values = values })
.SelectMany(
x => x.Values.DefaultIfEmpty(),
(x, value) => new DeviceParamValueDto
{
deviceCode = x.Param.deviceCode,
paramCode = x.Param.paramCode,
paramName = x.Param.paramName,
netWork = x.Param.netWork,
paramAddr = x.Param.paramAddr,
paramType = x.Param.paramType,
isFlag = x.Param.isFlag,
paramValue = value.Value.ToString(),
})
.ToList();
// 使用字典提高查找效率
var opcValueDict = opcItemValues.ToDictionary(v => v.NodeId, v => v);
//保存数据库
// 构建参数值列表和数据库实体列表
var paramValueList = new List<DeviceParamValueDto>();
var dbEntityList = new List<BaseDeviceParamVal>();
foreach (var param in deviceParams)
{
// 查找对应的OPC值
opcValueDict.TryGetValue(param.paramAddr, out var opcNode);
var paramValue = opcNode?.Value?.ToString() ?? string.Empty;
// 构建DTO
paramValueList.Add(new DeviceParamValueDto
{
deviceCode = param.deviceCode,
paramCode = param.paramCode,
paramName = param.paramName,
netWork = param.netWork,
paramAddr = param.paramAddr,
paramType = param.paramType,
isFlag = param.isFlag,
paramValue = paramValue,
});
// 构建数据库实体(批量插入)
dbEntityList.Add(new BaseDeviceParamVal
{
DEVICE_ID = device.objid,
DEVICE_CODE = device.deviceCode,
PARAM_CODE = param.paramCode,
PARAM_NAME = param.paramName,
PARAM_VALUE = paramValue,
COLLECT_TIME = now,
RECORD_TIME = now,
PARAM_TYPE = param.paramType,
});
}
paramValues = paramValueList;
// 批量保存到数据库(最高效的方式)
if (dbEntityList.Count > 0)
{
try
{
_paramValService.Insert(dbEntityList);
_serilog.Info($"设备{device.deviceCode}成功保存{dbEntityList.Count}条参数值到数据库");
}
catch (Exception ex)
{
_serilog.Info($"设备{device.deviceCode}保存参数值到数据库失败:{ex.Message}");
throw;
}
}
}
}

@ -38,6 +38,14 @@ public class AppConfig: IOptions<AppConfig>
/// Sql连接配置
/// </summary>
public List<SqlConfig> sqlConfig { get; set; }
/// <summary>
/// opc设备连接配置
/// </summary>
/// <typeparam name="OpcConfig"></typeparam>
/// <param name=""></param>
/// <returns></returns>
public List<OpcConfig> opcConfig { get;set; }
public AppConfig Value => this;
}

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sln.Imm.Daemon.Config
{
public class OpcConfig
{
/// <summary>
/// opc设备编号
/// </summary>
public string opcDeviceCode { get; set; }
/// <summary>
/// opc设备IP
/// </summary>
public string opcDeviceIp { get; set; }
/// <summary>
/// 是否启用
/// </summary>
public bool isFlag { get; set; }
}
}

@ -65,6 +65,12 @@ public class BaseDeviceInfo
[SugarColumn(ColumnName = "DEVICE_MODEL")]
public string deviceModel { get; set; }
/// <summary>
/// 设备厂商
/// </summary>
[SugarColumn(ColumnName = "MANUFACTURER")]
public string deviceFacture { get; set; }
/// <summary>
/// Desc:网络地址
/// Default:

@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SqlSugar;
namespace Sln.Imm.Daemon.Model.dao;
/// <summary>
/// 设备工艺参数当前值表
///</summary>
[SugarTable("BASE_DEVICE_PARAM_VAL"), TenantAttribute("mes")]
public class BaseDeviceParamVal
{
/// <summary>
/// 备 注:主键
///</summary>
[SugarColumn(ColumnName = "RECORD_ID", IsPrimaryKey = true)]
public decimal RECORD_ID { get; set; }
/// <summary>
/// 备 注:参数编号
///</summary>
[SugarColumn(ColumnName = "PARAM_CODE")]
public string? PARAM_CODE { get; set; }
/// <summary>
/// 备 注:设备编号
///</summary>
[SugarColumn(ColumnName = "DEVICE_CODE")]
public string? DEVICE_CODE { get; set; }
/// <summary>
/// 备 注:设备ID
///</summary>
[SugarColumn(ColumnName = "DEVICE_ID")]
public decimal? DEVICE_ID { get; set; }
/// <summary>
/// 备 注:参数名称
///</summary>
[SugarColumn(ColumnName = "PARAM_NAME")]
public string? PARAM_NAME { get; set; }
/// <summary>
/// 备 注:参数值
///</summary>
[SugarColumn(ColumnName = "PARAM_VALUE")]
public string? PARAM_VALUE { get; set; }
/// <summary>
/// 备 注:采集时间
///</summary>
[SugarColumn(ColumnName = "COLLECT_TIME")]
public DateTime? COLLECT_TIME { get; set; }
/// <summary>
/// 备 注:记录时间(默认当前时间)
///</summary>
[SugarColumn(ColumnName = "RECORD_TIME")]
public DateTime RECORD_TIME { get; set; }
/// <summary>
/// 备 注:参数类型
///</summary>
[SugarColumn(ColumnName = "PARAM_TYPE")]
public string? PARAM_TYPE { get; set; }
}

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sln.Imm.Daemon.Opc
{
public abstract class OpcDeviceFactory
{
/// <summary>
/// 是否连接
/// </summary>
public abstract bool IsConnected { get; set; }
/// <summary>
/// 建立连接
/// </summary>
/// <param name="ip"></param>
/// <param name="port"></param>
/// <returns></returns>
public abstract bool Connect(string ip, int port);
/// <summary>
/// 断开连接
/// </summary>
/// <returns></returns>
public abstract bool DisConnect();
}
}

@ -0,0 +1,64 @@
using Microsoft.Extensions.DependencyInjection;
using Sln.Imm.Daemon.Cache;
using Sln.Imm.Daemon.Config;
using Sln.Imm.Daemon.Model.dao;
using Sln.Imm.Daemon.Opc.Impl;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sln.Imm.Daemon.Opc
{
public static class OpcDeviceFactorySetup
{
public static void AddOpcDeviceFactorySetup(this IServiceCollection services)
{
services.AddSingleton<List<IOpcService>>(x =>
{
var _cacheService = x.GetService<BaseDeviceInfoCacheService>();
List<BaseDeviceInfo> deviceInfos = _cacheService.GetValueAsync("BaseDeviceInfoCache").Result;
List<IOpcService> opcs = new List<IOpcService>();
if (deviceInfos != null)
{
foreach (var item in deviceInfos)
{
if (item.isFlag == 1)
{
IOpcService opcDev = null;
if (item.deviceFacture.Contains("伊之密"))
{
opcDev = x.GetService<OpcUaService>();
}
else
{
opcDev = x.GetService<OpcDaService>();
}
if(opcDev != null)
{
var res = opcDev.ConnectAsync(item.networkAddress).Result;
if (!res)
{
Console.WriteLine($"{item.deviceName}设备连接失败");
}
else
{
opcs.Add(opcDev);
}
}
}
}
}
return opcs;
});
}
}
}

@ -13,7 +13,9 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Sln.Imm.Daemon.Cache\Sln.Imm.Daemon.Cache.csproj" />
<ProjectReference Include="..\Sln.Imm.Daemon.Model\Sln.Imm.Daemon.Model.csproj" />
<ProjectReference Include="..\Sln.Imm.Daemon.Serilog\Sln.Imm.Daemon.Serilog.csproj" />
</ItemGroup>
</Project>

@ -3,23 +3,23 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.35122.118
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sln.Imm.Daemon", "Sln.Imm.Daemon\Sln.Imm.Daemon.csproj", "{682DDE67-2CBF-4B54-831F-987EC6667FD1}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sln.Imm.Daemon", "Sln.Imm.Daemon\Sln.Imm.Daemon.csproj", "{682DDE67-2CBF-4B54-831F-987EC6667FD1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sln.Imm.Daemon.Config", "Sln.Imm.Daemon.Config\Sln.Imm.Daemon.Config.csproj", "{A08A7879-F8B6-4A34-8ABE-2DEE3309F225}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sln.Imm.Daemon.Config", "Sln.Imm.Daemon.Config\Sln.Imm.Daemon.Config.csproj", "{A08A7879-F8B6-4A34-8ABE-2DEE3309F225}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sln.Imm.Daemon.Serilog", "Sln.Imm.Daemon.Serilog\Sln.Imm.Daemon.Serilog.csproj", "{3D173F48-72EC-46F5-AB2E-2B0A1A1729B9}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sln.Imm.Daemon.Serilog", "Sln.Imm.Daemon.Serilog\Sln.Imm.Daemon.Serilog.csproj", "{3D173F48-72EC-46F5-AB2E-2B0A1A1729B9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sln.Imm.Daemon.Common", "Sln.Imm.Daemon.Common\Sln.Imm.Daemon.Common.csproj", "{728A030C-33EC-494C-AF86-ABC24B84AFD0}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sln.Imm.Daemon.Common", "Sln.Imm.Daemon.Common\Sln.Imm.Daemon.Common.csproj", "{728A030C-33EC-494C-AF86-ABC24B84AFD0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sln.Imm.Daemon.Model", "Sln.Imm.Daemon.Model\Sln.Imm.Daemon.Model.csproj", "{D0A7BFAC-A920-48E1-9F54-CA70DE7D01CF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sln.Imm.Daemon.Model", "Sln.Imm.Daemon.Model\Sln.Imm.Daemon.Model.csproj", "{D0A7BFAC-A920-48E1-9F54-CA70DE7D01CF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sln.Imm.Daemon.Repository", "Sln.Imm.Daemon.Repository\Sln.Imm.Daemon.Repository.csproj", "{BE51B37D-92B4-4561-92B6-D236300E33FA}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sln.Imm.Daemon.Repository", "Sln.Imm.Daemon.Repository\Sln.Imm.Daemon.Repository.csproj", "{BE51B37D-92B4-4561-92B6-D236300E33FA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sln.Imm.Daemon.Cache", "Sln.Imm.Daemon.Cache\Sln.Imm.Daemon.Cache.csproj", "{143CC5C4-661C-42A9-BEA0-3C6653347DE5}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sln.Imm.Daemon.Cache", "Sln.Imm.Daemon.Cache\Sln.Imm.Daemon.Cache.csproj", "{143CC5C4-661C-42A9-BEA0-3C6653347DE5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sln.Imm.Daemon.Business", "Sln.Imm.Daemon.Business\Sln.Imm.Daemon.Business.csproj", "{0D16FB81-A5E4-4599-8EF8-A0B130F12B7B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sln.Imm.Daemon.Business", "Sln.Imm.Daemon.Business\Sln.Imm.Daemon.Business.csproj", "{0D16FB81-A5E4-4599-8EF8-A0B130F12B7B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sln.Imm.Daemon.Opc", "Sln.Imm.Daemon.Opc\Sln.Imm.Daemon.Opc.csproj", "{05C0F145-6166-4939-9576-D208F2A69D1A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sln.Imm.Daemon.Opc", "Sln.Imm.Daemon.Opc\Sln.Imm.Daemon.Opc.csproj", "{05C0F145-6166-4939-9576-D208F2A69D1A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

@ -2,9 +2,11 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using NeoSmart.Caching.Sqlite;
using Newtonsoft.Json;
using Sln.Imm.Daemon.Business;
using Sln.Imm.Daemon.Cache;
using Sln.Imm.Daemon.Config;
using Sln.Imm.Daemon.Model.dto;
using Sln.Imm.Daemon.Opc;
using Sln.Imm.Daemon.Opc.Impl;
using Sln.Imm.Daemon.Repository;
@ -18,7 +20,7 @@ namespace Sln.Imm.Daemon
{
public static IServiceProvider? ServiceProvider = null;
static void Main(string[] args)
static async Task Main(string[] args)
{
var services = new ServiceCollection();
ConfigureServices(services);
@ -29,25 +31,37 @@ namespace Sln.Imm.Daemon
var log = ServiceProvider.GetService<SerilogHelper>();
log.Info($"系统启动成功,日志存放位置:{appConfig.logPath}");
var deviceCollectionBusiness = ServiceProvider.GetService<DeviceCollectionBusiness>();
deviceCollectionBusiness?.Handle();
//IOpcService _opcService = ServiceProvider.GetService<OpcUaService>();
//var result = _opcService.ConnectAsync("opc.tcp://192.168.0.100:62541/SharpNodeSettings/OpcUaServer").Result;
//if (result)
//{
// while (true)
// {
// var info = _opcService.ReadNodeAsync(new List<string>()
// {
// "ns=2;s=Devices/分厂一/车间一/测试空设备/压力",
// "ns=2;s=Devices/分厂一/车间一/测试空设备/温度",
// "ns=2;s=Devices/分厂一/车间一/测试空设备/条码"
// });
// var infos = _opcService.BrowseNodesAsync("ns=2;s=Devices/分厂一/车间一/测试空设备");
// Thread.Sleep(5000);
// }
//}
//var res = await _opcService.ConnectAsync("opc.tcp://10.10.63.102:4842");
var deviceCollectionBusiness = ServiceProvider.GetService<DeviceCollectionBusiness>();
//deviceCollectionBusiness?.Handle();
List<IOpcService> opcs = ServiceProvider.GetService<List<IOpcService>>();
if( opcs != null )
{
foreach( var opc in opcs)
{
var res = opc.ReadNodeAsync(new List<string>()
{
"ns=4;s=APPL.Core1.sv_CoreOutput.NormalIn.Velocity.Output.rOutputValue",
"ns=4;s=APPL.Core1.sv_CoreSetTimes.MoveIn.dSetMoveTime"
});
Console.WriteLine($"数据采集完成:{JsonConvert.SerializeObject(res)}");
Thread.Sleep(5000);
opc.DisconnectAsync();
Console.WriteLine($"断开设备连接");
}
}
Task.Delay(-1).Wait();
}
@ -90,9 +104,11 @@ namespace Sln.Imm.Daemon
.WithDistributedCache(
new SqliteCache(new SqliteCacheOptions
{
CachePath = "F:\\桌面\\数据缓存\\FusionCache.db"
CachePath = "D:\\working_area\\project\\澳柯玛注塑采集\\cache\\FusionCache.db"
//CachePath = "/Users/wenxiansheng/Public/WorkSpace/Mesnac/项目资料/澳柯玛注塑车间MES项目/数据缓存/FusionCache.db"
}));
services.AddOpcDeviceFactorySetup();
}
}
}

@ -7,7 +7,7 @@
"dbType": 3,
"isFlag": true,
//"connStr": "server=127.0.0.1;Port=4000;Database=tao_iot;Uid=root;"
"connStr": "Data Source=1.13.177.47:1521/helowin;User ID=c##aucma_mes;Password=aucma;"
"connStr": "Data Source=1.13.177.47:1521/helowin;User ID=haiwei;Password=aucma;"
}
]
}

Loading…
Cancel
Save