重写自动分配的逻辑
This commit is contained in:
parent
3ac7c7822a
commit
b8b6fde9b0
@ -1,4 +1,5 @@
|
||||
using DocumentFormat.OpenXml.Drawing.Spreadsheet;
|
||||
using DocumentFormat.OpenXml.Math;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using Learun.Application.Organization;
|
||||
using Learun.Application.TwoDevelopment.ZZDT_EC;
|
||||
@ -11,6 +12,10 @@ using Learun.Util.SqlSugar;
|
||||
using log4net.Config;
|
||||
using Microsoft.Practices.ObjectBuilder2;
|
||||
using Newtonsoft.Json;
|
||||
using NPOI.POIFS.Crypt;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using OfficeOpenXml;
|
||||
using OfficeOpenXml.Style;
|
||||
using Org.BouncyCastle.Bcpg.OpenPgp;
|
||||
using Pipelines.Sockets.Unofficial.Arenas;
|
||||
using SqlSugar;
|
||||
@ -18,9 +23,13 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity.Infrastructure;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web.Http;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using static Learun.Application.TwoDevelopment.ZZDT_EC.IO_WorkFlowService;
|
||||
using static Learun.Application.Web.Areas.ZZDT_EC.Controllers.ec_objecttypeController;
|
||||
|
||||
namespace Learun.Application.Web.AppApi
|
||||
{
|
||||
@ -49,14 +58,56 @@ namespace Learun.Application.Web.AppApi
|
||||
/// 根据模板自动创建端子排
|
||||
/// </summary>
|
||||
/// <param name="projId"></param>
|
||||
/// <param name="panelId"></param>
|
||||
/// <param name="panelObj"></param>
|
||||
/// <param name="seq"></param>
|
||||
/// <param name="TSname"></param>
|
||||
/// <param name="iOType"></param>
|
||||
private ec_PanelStripEntity CreatePanelStripByProfile2(string projId, string TSname, string panelId, GlobalEnum.IOType iOType)
|
||||
private ec_PanelStripEntity CreatePanelStripByProfile2(string projId, ec_PanelEntity panelObj, int seq, GlobalEnum.IOType iOType)
|
||||
{
|
||||
var setTb = ProjectSugar.TableName<ec_projectSettingsEntity>(projId);
|
||||
var allSettings = SqlSugarHelper.Db.Queryable<ec_projectSettingsEntity>().AS(setTb).ToList();
|
||||
allSettings = allSettings.FindAll(x => x.SettingName.StartsWith(GlobalObject.projSetting_IOCardProfile + iOType.ToString()));
|
||||
//IO_CardProfile
|
||||
return new ec_PanelStripEntity();
|
||||
//IO_CardProfile_DO_TermNoPerCh
|
||||
//IO_CardProfile_DO_CHNoPerStrip
|
||||
//IO_CardProfile_DO_ChNamePrefix
|
||||
//IO_CardProfile_DO_ChNameStartIndex
|
||||
var sName = GlobalObject.projSetting_IOCardProfile + iOType.ToString() + "_TermNoPerCh";
|
||||
var TermNoPerCh = allSettings.FirstOrDefault(x => x.SettingName == sName)?.SettingValue;
|
||||
sName = GlobalObject.projSetting_IOCardProfile + iOType.ToString() + "_CHNoPerStrip";
|
||||
var CHNoPerStrip = allSettings.FirstOrDefault(x => x.SettingName == sName)?.SettingValue;
|
||||
sName = GlobalObject.projSetting_IOCardProfile + iOType.ToString() + "_ChNamePrefix";
|
||||
var ChNamePrefix = allSettings.FirstOrDefault(x => x.SettingName == sName)?.SettingValue;
|
||||
if (int.TryParse(TermNoPerCh, out int iTermNoPerCh))
|
||||
{
|
||||
//err
|
||||
}
|
||||
if (int.TryParse(CHNoPerStrip, out int iCHNoPerStrip))
|
||||
{
|
||||
//err
|
||||
}
|
||||
var newTs = new ec_PanelStripEntity()
|
||||
{
|
||||
IO_TYPE = iOType.ToString(),
|
||||
PanelID = panelObj.PanelID,
|
||||
Panel_Strip_Seq = seq,
|
||||
StripName = "TS_" + iOType.ToString() + "_" + seq,
|
||||
TagNumber = "CreatePanelStripByProfile2"
|
||||
};
|
||||
newTs.Create();
|
||||
for (int i = 0; i < iCHNoPerStrip; i++)
|
||||
{
|
||||
var newCh = new ec_PanelChannelEntity()
|
||||
{
|
||||
ChannelName = ChNamePrefix + (i + 1).ToString(),
|
||||
Channel_Seq = i + 1,
|
||||
StripID = newTs.StripID,
|
||||
|
||||
};
|
||||
newCh.Create();
|
||||
newTs.Channels.Add(newCh);
|
||||
}
|
||||
return newTs;
|
||||
}
|
||||
/// <summary>
|
||||
/// 找到某一个预分配箱子 附近的某一个箱子。且io类型能匹配上
|
||||
@ -394,6 +445,36 @@ namespace Learun.Application.Web.AppApi
|
||||
}
|
||||
|
||||
ICache redisObj = CacheFactory.CaChe();
|
||||
|
||||
/// <summary>
|
||||
/// 导出分配结果
|
||||
/// </summary>
|
||||
/// <param name="projectId"></param>
|
||||
/// <param name="flg">是否为真实结果。step2时为false,step3后为true</param>
|
||||
[HttpGet]
|
||||
public void AutoAssignCable2Channel_ResExport(string projectId, bool flg)
|
||||
{
|
||||
var BLL = new ec_Wire_GroupBLL();
|
||||
var bytes = new byte[] { };
|
||||
try
|
||||
{
|
||||
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
|
||||
|
||||
using (var package = new ExcelPackage())//新建
|
||||
{
|
||||
var sheet = package.Workbook.Worksheets.Add("test");
|
||||
sheet.Cells[1, 1].Value = "test";
|
||||
bytes = package.GetAsByteArray();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log4net.LogManager.GetLogger("ERROR").Error("ec_PanelChannelBLL,IOModuleExportExcel 监控系统表导出" + ex.Message + ex.StackTrace);
|
||||
bytes = System.Text.Encoding.UTF8.GetBytes(ex.Message + ex.StackTrace);
|
||||
}
|
||||
var stream = new MemoryStream(bytes);
|
||||
FileDownHelper.DownLoad(stream, $"自动分配结果{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx");//自动化平台导出excel
|
||||
}
|
||||
/// <summary>
|
||||
/// 自动分配通道(点表信号自动分配)。
|
||||
///
|
||||
@ -522,9 +603,7 @@ namespace Learun.Application.Web.AppApi
|
||||
ICache redisObj = CacheFactory.CaChe();
|
||||
var cablesNeedAssigned = redisObj.Read<List<ec_CableEntity>>("IOModule_AutoAssign2Ch_" + projId, CacheId.IOModule_AutoAssign2Ch);
|
||||
|
||||
var setTb = ProjectSugar.TableName<ec_projectSettingsEntity>(projId);
|
||||
var allSettings = SqlSugarHelper.Db.Queryable<ec_projectSettingsEntity>().AS(setTb).ToList();
|
||||
//IO_CardProfile
|
||||
|
||||
|
||||
var signalTb = ProjectSugar.TableName<ec_Wire_GroupEntity>(projId);
|
||||
var allSignals = SqlSugarHelper.Db.Queryable<ec_Wire_GroupEntity>().AS(signalTb).ToList();
|
||||
@ -535,9 +614,9 @@ namespace Learun.Application.Web.AppApi
|
||||
.InnerJoin<ec_PanelStripTermEntity>((a, b) => a.TermID == b.TermID).AS<ec_PanelStripTermEntity>(termTb)
|
||||
.Select((a, b) => b.ChannelID).Distinct().ToList();
|
||||
|
||||
|
||||
var allUsedCH = allSignals.Where(x => !string.IsNullOrEmpty(x.ChannelID)).Select(x => x.ChannelID).Distinct().ToList();
|
||||
allUsedCH.AddRange(allConnedTerms);
|
||||
//包括2部分,1是已经被信号占用的通道,2是已经被接线端子占用的通道
|
||||
var allUsedCHBySignalOrSet = allSignals.Where(x => !string.IsNullOrEmpty(x.ChannelID)).Select(x => x.ChannelID).Distinct().ToList();
|
||||
allUsedCHBySignalOrSet.AddRange(allConnedTerms);
|
||||
//??这里有问题。通道是否被占用,需要看signal和set双重(在io分配界面)
|
||||
//1. 信号有, 电缆set有,占了
|
||||
//2.信号no,电缆set有,占了
|
||||
@ -545,32 +624,32 @@ namespace Learun.Application.Web.AppApi
|
||||
//4.信号no,电缆setno,没占
|
||||
|
||||
//1.2 流程图 分组原则为同一信号类型、同一系统的为一组
|
||||
var cablesGrouped = cablesNeedAssigned.OrderBy(x => x.PanelID).ThenBy(x => x.PreAssignIOType).ThenBy(x => x.System).ToList();
|
||||
var cablesGrouped = cablesNeedAssigned.OrderBy(x => x.AssignedPanel?.PanelID).ThenBy(x => x.PreAssignIOType).ThenBy(x => x.System).ToList();
|
||||
cablesGrouped = cablesGrouped.Where(x => x.Sets != null && x.Sets.Count() > 0 && x.AssignedPanel != null).ToList();//过滤掉没有set的,或者没有找到箱子的
|
||||
cablesGrouped = cablesGrouped.Where(x => x.Sets.Where(xx => !string.IsNullOrEmpty(xx.PreAssignGroup_Desc)).Count() > 0).ToList();//过滤掉set没有分配信号的
|
||||
|
||||
|
||||
var allPanelIds = cablesGrouped.Select(x => x.PanelID).Distinct();
|
||||
var allPanelIds = cablesGrouped.Select(x => x.AssignedPanel).Select(x => x.PanelID).Distinct().ToList();
|
||||
var stripBll = new ec_PanelStripBLL();
|
||||
var allStrips = stripBll.GetList("{ProjectId:\"" + projId + "\"}", OnlySelf: false)
|
||||
.Where(x => allPanelIds.Contains(x.PanelID))
|
||||
.GroupBy(x => x.PanelID)
|
||||
.ToDictionary(x => x.Key, x => x.ToList());
|
||||
//感觉逻辑上用panel来循环会更合理
|
||||
.ToDictionary(x => x.Key, x => x.ToList());//带出strip下的channel
|
||||
foreach (var curPanelId in allPanelIds)
|
||||
{
|
||||
int newTSSeq = 10001;
|
||||
|
||||
var curStrips = allStrips[curPanelId];
|
||||
var cablesOnThisPanel = cablesGrouped.Where(x => x.PanelID == curPanelId).ToList();
|
||||
if (cablesOnThisPanel == null || cablesOnThisPanel.Count == 0)
|
||||
{
|
||||
continue;//next panel
|
||||
}
|
||||
//var lastCableSystemAndIOType = cablesOnThisPanel.First().System + cablesOnThisPanel.First().PreAssignIOType;//用于判断是否是同一个组
|
||||
var existedStrips = allStrips[curPanelId];//已经存在的所有模块
|
||||
var cablesOnThisPanel = cablesGrouped.Where(x => x.AssignedPanel.PanelID == curPanelId).ToList();
|
||||
if (cablesOnThisPanel == null || cablesOnThisPanel.Count == 0) continue;//next panel
|
||||
var lastUsedStrip = (ec_PanelStripEntity)null;
|
||||
foreach (var cable in cablesOnThisPanel)
|
||||
{
|
||||
if (cable.CableID == "8c8ebc52-1ae3-4074-af53-e914dd178e78")
|
||||
{
|
||||
Console.Write("");
|
||||
}
|
||||
;
|
||||
//1.2.2 分组原则为同一信号类型、同一系统的为一组,系统属性从电缆的from端上的设备中取设备的系统,同组的优先放到同一个箱子的同一个模块里面,
|
||||
//如果一组放完后发现模块还有多余的通道可以放则下一个系统继续从这个模块开始分配。
|
||||
//???总感觉这句话,总结后:可以无脑用上一个模块,直到模块满了再用下一个模块。
|
||||
@ -590,159 +669,22 @@ namespace Learun.Application.Web.AppApi
|
||||
if (cable.PreAssignIOType.ToLower() == GlobalEnum.signalType.Digital.ToString().ToLower())
|
||||
{
|
||||
|
||||
if (setsIn.Count > 0 && setsOut.Count > 0)
|
||||
{
|
||||
//from cjj 25 09 23 wechat:一根电缆可能会出现既有输入也有输出,如果碰到就放到两个端子排里面,公共端不会出现一个输出,一个输入的
|
||||
continue;
|
||||
}
|
||||
//todo
|
||||
if (setsIn.Count > 0 && setsOut.Count > 0) continue;
|
||||
//from cjj 25 09 23 wechat:一根电缆可能会出现既有输入也有输出,如果碰到就放到两个端子排里面,公共端不会出现一个输出,一个输入的
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region inputNew
|
||||
if (setsIn.Count > 0)
|
||||
{
|
||||
var resIn = AutoAssignCore(GlobalEnum.inOrOut.输入, setsIn, setsSpared);
|
||||
var resIn = AutoAssignCore(GlobalEnum.inOrOut.输入, setsIn);
|
||||
}
|
||||
|
||||
#endregion
|
||||
#region input
|
||||
//ec_PanelStripEntity curStrip = null;
|
||||
//var matchedStrips = curStrips.Where(x => x.IO_TYPE == ioTypeOnCable.ToString()).ToList();
|
||||
//if (matchedStrips != null && lastUsedStrip != null && lastUsedStrip.IO_TYPE == ioTypeOnCable.ToString())
|
||||
//{
|
||||
// //1.2.2 优先使用上一个模块,直到模块满了再用下一个模块。
|
||||
// matchedStrips.Insert(0, lastUsedStrip);
|
||||
//}
|
||||
//if (setsIn.Count == 0 )
|
||||
//{
|
||||
// //相当于没有
|
||||
//}
|
||||
//else if (setsIn.Count + setsSpared.Count() > 10)
|
||||
//{
|
||||
// //另外如果电缆对数大于10对,即像12*2*0.75这种,无论它预分配了多少根电缆对,永远预留4个以下的空白通道。
|
||||
// //意思就是一个模块里面够4个或4个以上空白通道就留4个空白通道,
|
||||
// //如果不够4个就留4个以下即可。
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// string PanelName = cable.AssignedPanel.TagNumber;//当前电缆预分配的箱子名称
|
||||
// switch (cable.PreAssignIOType.ToLower())
|
||||
// {
|
||||
// case "digital":
|
||||
// //数字量
|
||||
// ioTypeOnCable = GlobalEnum.IOType.DI;
|
||||
// break;
|
||||
// case "4~20ma":
|
||||
// //模拟量4-20mA
|
||||
// ioTypeOnCable = GlobalEnum.IOType.AI;
|
||||
// break;
|
||||
// case "10v":
|
||||
// ioTypeOnCable = GlobalEnum.IOType.TenVolt;
|
||||
// break;
|
||||
// case "pt100":
|
||||
// ioTypeOnCable = GlobalEnum.IOType.PT100;
|
||||
// break;
|
||||
// case "pulse":
|
||||
// ioTypeOnCable = GlobalEnum.IOType.PULSE;
|
||||
// break;
|
||||
// default:
|
||||
// //通讯类 485 422啥的
|
||||
// continue;
|
||||
// break;
|
||||
// }
|
||||
|
||||
// //1.2 流程图 箱子里是否已经存在端子排(io匹配)
|
||||
|
||||
// bool alreadyInsertNewTs = false;
|
||||
// if (matchedStrips == null || matchedStrips.Count == 0)
|
||||
// {
|
||||
// //没有端子排
|
||||
// //1.2 流程图 根据信号数里自动新建端子排,端子排通道数里根据箱子模板中的默认值获得
|
||||
// var newTS = CreatePanelStripByProfile2(projId, "TS_" + ioTypeOnCable.ToString() + "_" + newTSSeq++, curPanelId, ioTypeOnCable);
|
||||
// alreadyInsertNewTs = true;
|
||||
// matchedStrips.Add(newTS);
|
||||
// }
|
||||
|
||||
// #region 1.2 流程图 空的通道数够不够
|
||||
// if (cable.CableClass == SWS.Share.Enum.cableClass.homerun.ToString())
|
||||
// {
|
||||
// //1.2.3(2)如果模块是通讯信号(像RS485这种就是通讯信号),则不用管预留空白通道这个事情,看到有空的通道就放。
|
||||
// //当前这个端子排就是可用的
|
||||
|
||||
// curStrip = matchedStrips.First();
|
||||
|
||||
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //1.2.3 (1) 非通讯,如果空的通道大于整个模块的5%,则可以利用,利用到小于5%了则停止利用,如果本身空通道数占的比例就小于5%,则不利用。
|
||||
|
||||
// curStrip = FindNextAvailableTS(matchedStrips, allUsedCH);
|
||||
|
||||
// if (curStrip == null)
|
||||
// {
|
||||
// var newTS = CreatePanelStripByProfile2(projId, "TS_" + ioTypeOnCable.ToString() + "_" + newTSSeq++, curPanelId, ioTypeOnCable);
|
||||
// alreadyInsertNewTs = true;
|
||||
// matchedStrips.Add(newTS);
|
||||
// curStrip = newTS;
|
||||
|
||||
// }
|
||||
// }
|
||||
// var usedChs = curStrip.Channels.Where(x => allUsedCH.Contains(x.ChannelID)).Select(x => x.ChannelID).ToList();
|
||||
// var notUsedChs = curStrip.Channels.Where(x => !usedChs.Contains(x.ChannelID)).ToList();
|
||||
// #endregion
|
||||
// #region 1.2 流程图 按规则先放几个信号进去
|
||||
// if (notUsedChs.Count < setsIn.Count + setsSpared.Count())
|
||||
// {
|
||||
// //不够放,又要新建?
|
||||
// if (alreadyInsertNewTs)
|
||||
// {
|
||||
// //压根就有问题,说明电缆的set太多了,就算是新建的模块,一个channel都没有使用的情况下,都塞不下。
|
||||
// continue;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //相当于前面5%的判断过了,但是呢放不下所有需要的set
|
||||
// var newTS = CreatePanelStripByProfile2(projId, "TS_" + ioTypeOnCable.ToString() + "_" + newTSSeq++, curPanelId, ioTypeOnCable);
|
||||
// alreadyInsertNewTs = true;
|
||||
// matchedStrips.Add(newTS);
|
||||
// curStrip = newTS;
|
||||
// usedChs = curStrip.Channels.Where(x => allUsedCH.Contains(x.ChannelID)).Select(x => x.ChannelID).ToList();
|
||||
// notUsedChs = curStrip.Channels.Where(x => !usedChs.Contains(x.ChannelID)).ToList();
|
||||
// if (notUsedChs.Count < setsIn.Count + setsSpared.Count())
|
||||
// {
|
||||
// //压根就有问题,说明电缆的set太多了,就算是新建的模块,一个channel都没有使用的情况下,都塞不下。
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// lastUsedStrip = curStrip;
|
||||
// //能放下
|
||||
// for (int i = 0; i < setsIn.Count; i++)
|
||||
// {
|
||||
// var set = setsIn[i];
|
||||
// var ch = notUsedChs[i];
|
||||
// set.ConnectionInfo = $"采集箱:{PanelName}/模块(端子排):{curStrip.StripName}/通道:{ch.ChannelName}";
|
||||
// //更新全局已使用通道
|
||||
// allUsedCH.Add(ch.ChannelID);
|
||||
// }
|
||||
// var chOffIdx = setsIn.Count;
|
||||
// for (int i = 0; i < setsSpared.Count(); i++)
|
||||
// {
|
||||
// var set = setsSpared[i];
|
||||
// var ch = notUsedChs[chOffIdx + i];
|
||||
// set.ConnectionInfo = $"采集箱:{PanelName}/模块(端子排):{curStrip.StripName}/通道:{ch.ChannelName}/冗余";
|
||||
// //更新全局已使用通道
|
||||
// allUsedCH.Add(ch.ChannelID);
|
||||
// }
|
||||
// #endregion
|
||||
//}
|
||||
#endregion
|
||||
#endregion
|
||||
#region output
|
||||
if (setsOut.Count > 0)
|
||||
{
|
||||
var resOut = AutoAssignCore(GlobalEnum.inOrOut.输出, setsOut, setsSpared);
|
||||
var resOut = AutoAssignCore(GlobalEnum.inOrOut.输出, setsOut);
|
||||
|
||||
}
|
||||
|
||||
@ -750,7 +692,7 @@ namespace Learun.Application.Web.AppApi
|
||||
#endregion
|
||||
|
||||
//in 和 out都会执行这个
|
||||
bool AutoAssignCore(GlobalEnum.inOrOut inOrOut, List<ec_CableSetEntity> sets, List<ec_CableSetEntity> sets_Spared)
|
||||
bool AutoAssignCore(GlobalEnum.inOrOut inOrOut, List<ec_CableSetEntity> sets)
|
||||
{
|
||||
GlobalEnum.IOType ioTypeOnC = default;
|
||||
switch (cable.PreAssignIOType.ToLower())
|
||||
@ -792,111 +734,444 @@ namespace Learun.Application.Web.AppApi
|
||||
return false;
|
||||
}
|
||||
|
||||
ec_PanelStripEntity curStrip = null;
|
||||
var matchedStrips = curStrips.Where(x => x.IO_TYPE == ioTypeOnC.ToString()).ToList();
|
||||
|
||||
var matchedStrips = existedStrips.Where(x => x.IO_TYPE == ioTypeOnC.ToString()).ToList();//这个电缆下符合的模块
|
||||
if (matchedStrips != null && lastUsedStrip != null && lastUsedStrip.IO_TYPE == ioTypeOnC.ToString())
|
||||
{
|
||||
//1.2.2 优先使用上一个模块,直到模块满了再用下一个模块。
|
||||
matchedStrips.Insert(0, lastUsedStrip);
|
||||
matchedStrips.Remove(lastUsedStrip);
|
||||
matchedStrips.Insert(0, lastUsedStrip);//???????
|
||||
}
|
||||
|
||||
if (matchedStrips == null || matchedStrips.Count == 0)
|
||||
{
|
||||
#region NewTS
|
||||
|
||||
//1.2 流程图 根据信号数里自动新建端子排,端子排通道数里根据箱子模板中的默认值获得
|
||||
var newTS = CreatePanelStripByProfile2(projId, cable.AssignedPanel, newTSSeq++, ioTypeOnC);
|
||||
|
||||
matchedStrips.Add(newTS);
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
string PanelName = cable.AssignedPanel.TagNumber;//当前电缆预分配的箱子名称
|
||||
if (sets.Count == 0)
|
||||
if (sets.Count == 0) return false;
|
||||
|
||||
|
||||
//1.2 流程图 箱子里是否已经存在端子排(io匹配)
|
||||
List<ec_PanelChannelEntity> usedChs = new List<ec_PanelChannelEntity>();
|
||||
List<ec_PanelChannelEntity> notUsedChs = new List<ec_PanelChannelEntity>();
|
||||
if (cable.CableClass == SWS.Share.Enum.cableClass.homerun.ToString())
|
||||
{
|
||||
//相当于没有
|
||||
//1.2.3(2)如果模块是通讯信号(像RS485这种就是通讯信号),则不用管预留空白通道这个事情,看到有空的通道就放。
|
||||
//当前这个端子排就是可用的
|
||||
|
||||
//?????????????????????????????????????
|
||||
|
||||
}
|
||||
else
|
||||
#region 1.2 流程图 按规则先放几个信号进去(放不下就延到下一个模块)
|
||||
//if (cable.Sets.Count > 10)
|
||||
//{
|
||||
// //另外如果电缆对数大于10对,即像12 * 2 * 0.75这种,无论它预分配了多少根电缆对,永远预留4个以下的空白通道。意思就是一个模块里面够4个或4个以上空白通道就留4个空白通道,如果不够4个就留4个以下即可。
|
||||
// #region FindNextAvailableTS(可能多个)
|
||||
// //还分2种情况判断模块是否符合:
|
||||
// //case1,. 占满可用通道后,还剩至少一个预分配的set和spared的set。 //这种时候要spared不用考虑
|
||||
// //case2,. 占满可用通道后(或者没占满通道,预分配set已经没了),只剩下spared的set。 //这种时候要确保spared也能放下
|
||||
|
||||
// bool NeedNextTS = false;
|
||||
// do
|
||||
// {
|
||||
// #region FindNextAvailableTS
|
||||
// var availableTS = new List<ec_PanelStripEntity>();
|
||||
// foreach (var TS in matchedStrips)
|
||||
// {
|
||||
// var allCh = TS.Channels;
|
||||
// //被占用的(wt里有或者信号里或有),或者被锁定的,都算占用
|
||||
// usedChs = allCh.Where(x => allUsedCHBySignalOrSet.Contains(x.ChannelID) || x.lock_flg == 1).ToList();
|
||||
// notUsedChs = allCh.Where(x => !usedChs.Select(c => c.ChannelID).Contains(x.ChannelID)).ToList();
|
||||
// if (notUsedChs.Count < sets.Count)
|
||||
// {
|
||||
// //case1,能顺利接完,set还有多
|
||||
// //这种时候不需要考虑spared
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //case2,占满可用通道后(或者没占满通道,预分配set已经没了),只剩下spared的set
|
||||
// //想办法留出4个
|
||||
// //这种时候要确保spared也能放下
|
||||
// if (notUsedChs.Count < sets.Count + setsSpared.Count)
|
||||
// {
|
||||
// //放不下,换下一个模块
|
||||
// continue;
|
||||
// }
|
||||
// var sparedSetFor10 = notUsedChs.Count - sets.Count - setsSpared.Count;//16-9-5=2
|
||||
// if (sparedSetFor10 > 4)
|
||||
// {
|
||||
// //固定流出后面4个,相当于不要了
|
||||
// var last4 = allCh.Skip(allCh.Count - 4).ToList();
|
||||
// usedChs = allCh.Take(allCh.Count - 4).Where(x => allUsedCHBySignalOrSet.Contains(x.ChannelID) || x.lock_flg == 1).ToList();
|
||||
// usedChs.AddRange(last4);
|
||||
// notUsedChs = allCh.Take(allCh.Count - 4).Where(x => !usedChs.Select(c => c.ChannelID).Contains(x.ChannelID)).ToList();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //不够4个,就留多少是多少
|
||||
// var lastN = allCh.Skip(allCh.Count - sparedSetFor10).ToList();
|
||||
// usedChs = allCh.Take(allCh.Count - sparedSetFor10).Where(x => allUsedCHBySignalOrSet.Contains(x.ChannelID) || x.lock_flg == 1).ToList();
|
||||
// usedChs.AddRange(lastN);
|
||||
// notUsedChs = allCh.Take(allCh.Count - sparedSetFor10).Where(x => !usedChs.Select(c => c.ChannelID).Contains(x.ChannelID)).ToList();
|
||||
// }
|
||||
// }
|
||||
// //1.2 流程图 空的通道数够不够
|
||||
// double sparedRate = notUsedChs.Count * 1.0 / allCh.Count * 1.0;
|
||||
// if (sparedRate < 0.05)
|
||||
// {
|
||||
// //没有空闲通道 next
|
||||
// //或者空闲通道不够放下这个电缆的所有set
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// TS.Channels = allCh.OrderBy(X => X.Channel_Seq).ToList();//不能像之前一样过滤掉,否则下一个电缆进来时,总数就不对了。
|
||||
|
||||
// TS.ChannelsSpared = notUsedChs.Count;
|
||||
// TS.ChannelsUsed = usedChs.Count;
|
||||
// availableTS.Add(TS);//所有5%以上空闲通道的模块
|
||||
// break;
|
||||
// }
|
||||
|
||||
|
||||
// }
|
||||
// #endregion
|
||||
// #region NewTS
|
||||
// if (availableTS.Count() == 0)
|
||||
// {
|
||||
// //1.2 流程图 根据信号数里自动新建端子排,端子排通道数里根据箱子模板中的默认值获得
|
||||
// var newTS = CreatePanelStripByProfile2(projId, cable.AssignedPanel, newTSSeq++, ioTypeOnC);
|
||||
// //matchedStrips.Add(newTS);
|
||||
// var allCh = newTS.Channels;
|
||||
// notUsedChs = newTS.Channels.ToList();
|
||||
// newTS.ChannelsSpared = notUsedChs.Count;
|
||||
// newTS.ChannelsUsed = 0;
|
||||
// usedChs = new List<ec_PanelChannelEntity>();//新建的没有被占用的
|
||||
// availableTS.Add(newTS);
|
||||
|
||||
// if (notUsedChs.Count < sets.Count)
|
||||
// {
|
||||
// //case1,能顺利接完,set还有多
|
||||
// //这种时候不需要考虑spared
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //case2,占满可用通道后(或者没占满通道,预分配set已经没了),只剩下spared的set
|
||||
// //想办法留出4个
|
||||
// //这种时候要确保spared也能放下
|
||||
// if (notUsedChs.Count < sets.Count + setsSpared.Count)
|
||||
// {
|
||||
// //放不下,换下一个模块
|
||||
// continue;
|
||||
// }
|
||||
// var sparedSetFor10 = notUsedChs.Count - sets.Count - setsSpared.Count;//16-9-5=2
|
||||
// if (sparedSetFor10 > 4)
|
||||
// {
|
||||
// //固定流出后面4个,相当于不要了
|
||||
// var last4 = allCh.Skip(allCh.Count - 4).ToList();
|
||||
// usedChs = allCh.Take(allCh.Count - 4).Where(x => allUsedCHBySignalOrSet.Contains(x.ChannelID) || x.lock_flg == 1).ToList();
|
||||
// usedChs.AddRange(last4);
|
||||
// notUsedChs = allCh.Take(allCh.Count - 4).Where(x => !usedChs.Select(c => c.ChannelID).Contains(x.ChannelID)).ToList();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //不够4个,就留多少是多少
|
||||
// var lastN = allCh.Skip(allCh.Count - sparedSetFor10).ToList();
|
||||
// usedChs = allCh.Take(allCh.Count - sparedSetFor10).Where(x => allUsedCHBySignalOrSet.Contains(x.ChannelID) || x.lock_flg == 1).ToList();
|
||||
// usedChs.AddRange(lastN);
|
||||
// notUsedChs = allCh.Take(allCh.Count - sparedSetFor10).Where(x => !usedChs.Select(c => c.ChannelID).Contains(x.ChannelID)).ToList();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// #endregion
|
||||
// lastUsedStrip = availableTS.Last();
|
||||
|
||||
// if (notUsedChs.Count < sets.Count)
|
||||
// {
|
||||
// //case1,分配完后,还有多的set和可能的spared
|
||||
// //先这部分填完
|
||||
// //到5%为止的数量
|
||||
// var countOnThisTS = Math.Round(0.5 + notUsedChs.Count * 0.95);
|
||||
// for (int i = 0; i < countOnThisTS; i++)
|
||||
// {
|
||||
// var set = sets[i];
|
||||
// var ch = notUsedChs[i];
|
||||
// if (lastUsedStrip.TagNumber == "CreatePanelStripByProfile2")
|
||||
// {
|
||||
// set.ConnectionInfo = $"采集箱:{PanelName}/模块(端子排):(自动创建){lastUsedStrip.StripName}/通道:{ch.ChannelName}";
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// set.ConnectionInfo = $"采集箱:{PanelName}/模块(端子排):(原本存在){lastUsedStrip.StripName}/通道:{ch.ChannelName}";
|
||||
// }
|
||||
// ch.FakeGroupDesc = set.PreAssignGroup_Desc;
|
||||
// ch.FakeSignalType = set.IOType.ToString();
|
||||
// ch.lock_flg = 1;
|
||||
// set.IsConned = true;
|
||||
// //更新全局已使用通道
|
||||
// allUsedCHBySignalOrSet.Add(ch.ChannelID);
|
||||
|
||||
// }
|
||||
// //set会剩
|
||||
// NeedNextTS = true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //case2,分配完后,没有多的set了,可能还有spared
|
||||
// //上面已经判断过了,确保spared也是够的
|
||||
// var countMin = Math.Min(sets.Count, notUsedChs.Count);
|
||||
// for (int i = 0; i < countMin; i++)
|
||||
// {
|
||||
// var set = sets[i];
|
||||
// var ch = notUsedChs[i];
|
||||
// if (lastUsedStrip.TagNumber == "CreatePanelStripByProfile2")
|
||||
// {
|
||||
// set.ConnectionInfo = $"采集箱:{PanelName}/模块(端子排):(自动创建){lastUsedStrip.StripName}/通道:{ch.ChannelName}";
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// set.ConnectionInfo = $"采集箱:{PanelName}/模块(端子排):(原本存在){lastUsedStrip.StripName}/通道:{ch.ChannelName}";
|
||||
// }
|
||||
// ch.FakeGroupDesc = set.PreAssignGroup_Desc;
|
||||
// ch.FakeSignalType = set.IOType.ToString();
|
||||
// ch.lock_flg = 1;
|
||||
// set.IsConned = true;
|
||||
// //更新全局已使用通道
|
||||
// allUsedCHBySignalOrSet.Add(ch.ChannelID);
|
||||
|
||||
// }
|
||||
// #region spared
|
||||
// for (int i = 0; i < setsSpared.Count(); i++)
|
||||
// {
|
||||
// var set = setsSpared[i];
|
||||
// var ch = notUsedChs[countMin + i];
|
||||
// if (lastUsedStrip.TagNumber == "CreatePanelStripByProfile2")
|
||||
// {
|
||||
// set.ConnectionInfo = $"采集箱:{PanelName}/模块(端子排):(自动创建){lastUsedStrip.StripName}/通道:{ch.ChannelName}/冗余";
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// set.ConnectionInfo = $"采集箱:{PanelName}/模块(端子排):(原本存在){lastUsedStrip.StripName}/通道:{ch.ChannelName}/冗余";
|
||||
// }
|
||||
// ch.FakeGroupDesc = "预留";
|
||||
// ch.lock_flg = 1;
|
||||
// //更新全局已使用通道
|
||||
// allUsedCHBySignalOrSet.Add(ch.ChannelID);
|
||||
// }
|
||||
// NeedNextTS = false;
|
||||
// #endregion
|
||||
// }
|
||||
// sets = sets.Where(x => !x.IsConned).ToList();//移除已经分配过的set
|
||||
// } while (NeedNextTS);
|
||||
|
||||
// #endregion
|
||||
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
//5%的空白通道
|
||||
#region FindNextAvailableTS(可能多个)
|
||||
//还分2种情况判断模块是否符合:
|
||||
//case1,. 占满可用通道后,还剩至少一个预分配的set和spared的set。 //这种时候要spared不用考虑
|
||||
//case2,. 占满可用通道后(或者没占满通道,预分配set已经没了),只剩下spared的set。 //这种时候要确保spared也能放下
|
||||
//case3, 刚好,只有spared可能多
|
||||
bool NeedNextTS = false;
|
||||
|
||||
#region FindNextAvailableTS
|
||||
int idx = 0;
|
||||
while (idx < matchedStrips.Count)
|
||||
{
|
||||
var totalSets = sets.Count + setsSpared.Count();
|
||||
//1.2 流程图 箱子里是否已经存在端子排(io匹配)
|
||||
|
||||
bool alreadyInsertNewTs = false;
|
||||
if (matchedStrips == null || matchedStrips.Count == 0)
|
||||
NeedNextTS = false;
|
||||
var TS = matchedStrips[idx];
|
||||
var allCh = TS.Channels;
|
||||
var allChCount = allCh.Count;
|
||||
if (allChCount == 0)
|
||||
{
|
||||
//没有端子排
|
||||
//1.2 流程图 根据信号数里自动新建端子排,端子排通道数里根据箱子模板中的默认值获得
|
||||
var newTS = CreatePanelStripByProfile2(projId, "TS_" + ioTypeOnC.ToString() + "_" + newTSSeq++, curPanelId, ioTypeOnC);
|
||||
alreadyInsertNewTs = true;
|
||||
matchedStrips.Add(newTS);
|
||||
NeedNextTS = true;
|
||||
//同时又是最后一个了
|
||||
if (idx == matchedStrips.Count - 1)
|
||||
{
|
||||
var newTS = CreatePanelStripByProfile2(projId, cable.AssignedPanel, newTSSeq++, ioTypeOnC);
|
||||
if (newTS.Channels.Count() < setsSpared.Count + 1)//1代表至少要放一个set
|
||||
{
|
||||
//有问题了 panel的io模板,估计会导致无限循环了
|
||||
break;
|
||||
}
|
||||
matchedStrips.Add(newTS);
|
||||
}
|
||||
idx++; continue;//本模块没有一个ch
|
||||
}
|
||||
|
||||
#region 1.2 流程图 空的通道数够不够
|
||||
if (cable.CableClass == SWS.Share.Enum.cableClass.homerun.ToString())
|
||||
//被占用的(wt里有或者信号里或有),或者被锁定的,都算占用
|
||||
usedChs = allCh.Where(x => allUsedCHBySignalOrSet.Contains(x.ChannelID) || x.lock_flg == 1).ToList();
|
||||
notUsedChs = allCh.Where(x => !usedChs.Select(c => c.ChannelID).Contains(x.ChannelID)).ToList();
|
||||
//1.2 流程图 空的通道数够不够
|
||||
double sparedRate = notUsedChs.Count * 1.0 / allChCount * 1.0;
|
||||
if (sparedRate < 0.05)
|
||||
{
|
||||
//1.2.3(2)如果模块是通讯信号(像RS485这种就是通讯信号),则不用管预留空白通道这个事情,看到有空的通道就放。
|
||||
//当前这个端子排就是可用的
|
||||
|
||||
curStrip = matchedStrips.First();
|
||||
|
||||
NeedNextTS = true;
|
||||
//同时又是最后一个了
|
||||
if (idx == matchedStrips.Count - 1)
|
||||
{
|
||||
var newTS = CreatePanelStripByProfile2(projId, cable.AssignedPanel, newTSSeq++, ioTypeOnC);
|
||||
if (newTS.Channels.Count() < setsSpared.Count + 1)//1代表至少要放一个set
|
||||
{
|
||||
//有问题了 panel的io模板,估计会导致无限循环了
|
||||
break;
|
||||
}
|
||||
matchedStrips.Add(newTS);
|
||||
}
|
||||
idx++; continue;//本模块可用的模块小于5%
|
||||
}
|
||||
//没有空闲通道 next
|
||||
//或者空闲通道不够放下这个电缆的所有set
|
||||
//算一下5%是多少个通道
|
||||
var trueAvailableChs =notUsedChs.Count- (allChCount- FindMaxNumberChannel(allChCount));//真正能用的(没接过的,然后去掉5%)
|
||||
var ChNeedConn = 0;
|
||||
var SparedNeedConn = 0;
|
||||
if (trueAvailableChs < sets.Count)
|
||||
{
|
||||
//case1,能顺利接完,set还有多,还要再do循环一次,多余的set和spared都要放到下一个模块
|
||||
NeedNextTS = true;
|
||||
ChNeedConn = trueAvailableChs; SparedNeedConn = 0;
|
||||
}
|
||||
else if (trueAvailableChs == sets.Count)
|
||||
{
|
||||
//case3,刚好,只有spared可能多
|
||||
if (setsSpared.Count > 0)
|
||||
{
|
||||
//自己的感觉(非客户word需求里的原话):spared不能自己单独占用一个模块
|
||||
NeedNextTS = true;
|
||||
ChNeedConn = trueAvailableChs - 1;//留一个给spared
|
||||
SparedNeedConn = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ChNeedConn = trueAvailableChs; SparedNeedConn = 0;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//1.2.3 (1) 非通讯,如果空的通道大于整个模块的5%,则可以利用,利用到小于5%了则停止利用,如果本身空通道数占的比例就小于5%,则不利用。
|
||||
|
||||
curStrip = FindNextAvailableTS(cable.Sets.Count,totalSets, matchedStrips, allUsedCH);
|
||||
|
||||
if (curStrip == null)
|
||||
//maxCh > sets.Count
|
||||
//case2,占满可用通道后(或者没占满通道,预分配set已经没了),只剩下spared的set
|
||||
if (setsSpared.Count == 0)
|
||||
{
|
||||
var newTS = CreatePanelStripByProfile2(projId, "TS_" + ioTypeOnC.ToString() + "_" + newTSSeq++, curPanelId, ioTypeOnC);
|
||||
alreadyInsertNewTs = true;
|
||||
matchedStrips.Add(newTS);
|
||||
curStrip = newTS;
|
||||
|
||||
//ok
|
||||
ChNeedConn = sets.Count; SparedNeedConn = 0;
|
||||
}
|
||||
}
|
||||
var usedChs = curStrip.Channels.Where(x => allUsedCH.Contains(x.ChannelID)).Select(x => x.ChannelID).ToList();
|
||||
var notUsedChs = curStrip.Channels.Where(x => !usedChs.Contains(x.ChannelID)).ToList();
|
||||
#endregion
|
||||
#region 1.2 流程图 按规则先放几个信号进去
|
||||
if (notUsedChs.Count < totalSets)
|
||||
{
|
||||
//不够放,又要新建?
|
||||
if (alreadyInsertNewTs)
|
||||
//这种时候要确保spared也能放下
|
||||
else if (trueAvailableChs < sets.Count + setsSpared.Count)
|
||||
{
|
||||
//压根就有问题,说明电缆的set太多了,就算是新建的模块,一个channel都没有使用的情况下,都塞不下。
|
||||
return false;
|
||||
//自己的感觉(非客户word需求里的原话):spared不能自己单独占用一个模块
|
||||
ChNeedConn = trueAvailableChs - 1;//留一个给spared
|
||||
NeedNextTS = true;
|
||||
SparedNeedConn = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//相当于前面5%的判断过了,但是呢放不下所有需要的set
|
||||
var newTS = CreatePanelStripByProfile2(projId, "TS_" + ioTypeOnC.ToString() + "_" + newTSSeq++, curPanelId, ioTypeOnC);
|
||||
alreadyInsertNewTs = true;
|
||||
matchedStrips.Add(newTS);
|
||||
curStrip = newTS;
|
||||
usedChs = curStrip.Channels.Where(x => allUsedCH.Contains(x.ChannelID)).Select(x => x.ChannelID).ToList();
|
||||
notUsedChs = curStrip.Channels.Where(x => !usedChs.Contains(x.ChannelID)).ToList();
|
||||
if (notUsedChs.Count < sets.Count + setsSpared.Count())
|
||||
{
|
||||
//压根就有问题,说明电缆的set太多了,就算是新建的模块,一个channel都没有使用的情况下,都塞不下。
|
||||
return false;
|
||||
}
|
||||
{
|
||||
//ok,set和spared都能放下
|
||||
ChNeedConn = sets.Count;
|
||||
SparedNeedConn = setsSpared.Count;
|
||||
}
|
||||
}
|
||||
lastUsedStrip = curStrip;
|
||||
|
||||
for (int i = 0; i < sets.Count; i++)
|
||||
//到这里,说明本模块至少都是可用的
|
||||
|
||||
TS.Channels = allCh.OrderBy(X => X.Channel_Seq).ToList();//不能像之前一样过滤掉,否则下一个电缆进来时,总数就不对了。
|
||||
|
||||
lastUsedStrip = TS;
|
||||
|
||||
|
||||
#region conn
|
||||
|
||||
for (int i = 0; i < ChNeedConn; i++)
|
||||
{
|
||||
var set = sets[i];
|
||||
var ch = notUsedChs[i];
|
||||
set.ConnectionInfo = $"采集箱:{PanelName}/模块(端子排):{curStrip.StripName}/通道:{ch.ChannelName}";
|
||||
if (lastUsedStrip.TagNumber == "CreatePanelStripByProfile2")
|
||||
{
|
||||
set.ConnectionInfo = $"采集箱:{PanelName}/模块(端子排):(自动创建){lastUsedStrip.StripName}/通道:{ch.ChannelName}";
|
||||
}
|
||||
else
|
||||
{
|
||||
set.ConnectionInfo = $"采集箱:{PanelName}/模块(端子排):(原本存在){lastUsedStrip.StripName}/通道:{ch.ChannelName}";
|
||||
}
|
||||
ch.FakeGroupDesc = set.PreAssignGroup_Desc;
|
||||
ch.FakeSignalType = set.IOType.ToString();
|
||||
ch.lock_flg = 1;
|
||||
set.IsConned = true;
|
||||
//更新全局已使用通道
|
||||
allUsedCH.Add(ch.ChannelID);
|
||||
allUsedCHBySignalOrSet.Add(ch.ChannelID);
|
||||
|
||||
}
|
||||
var chOffIdx = sets.Count;
|
||||
for (int i = 0; i < setsSpared.Count(); i++)
|
||||
#endregion
|
||||
#region spared
|
||||
for (int i = 0; i < SparedNeedConn; i++)
|
||||
{
|
||||
var set = setsSpared[i];
|
||||
var ch = notUsedChs[chOffIdx + i];
|
||||
set.ConnectionInfo = $"采集箱:{PanelName}/模块(端子排):{curStrip.StripName}/通道:{ch.ChannelName}/冗余";
|
||||
var ch = notUsedChs[ChNeedConn + i];
|
||||
if (lastUsedStrip.TagNumber == "CreatePanelStripByProfile2")
|
||||
{
|
||||
set.ConnectionInfo = $"采集箱:{PanelName}/模块(端子排):(自动创建){lastUsedStrip.StripName}/通道:{ch.ChannelName}/冗余";
|
||||
}
|
||||
else
|
||||
{
|
||||
set.ConnectionInfo = $"采集箱:{PanelName}/模块(端子排):(原本存在){lastUsedStrip.StripName}/通道:{ch.ChannelName}/冗余";
|
||||
}
|
||||
ch.lock_flg = 1;
|
||||
//更新全局已使用通道
|
||||
allUsedCH.Add(ch.ChannelID);
|
||||
allUsedCHBySignalOrSet.Add(ch.ChannelID);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
//shi否要继续
|
||||
TS.ChannelsSpared = notUsedChs.Where(x=>x.lock_flg !=1).Count();
|
||||
TS.ChannelsUsed = allChCount - TS.ChannelsSpared;// usedChs.Count + (notUsedChs.Where(x => x.lock_flg == 1).Count());
|
||||
if (NeedNextTS)
|
||||
{
|
||||
sets = sets.Where(x => !x.IsConned ?? false).ToList();//移除已经分配过的set
|
||||
//同时又是最后一个了
|
||||
if (idx == matchedStrips.Count - 1)
|
||||
{
|
||||
var newTS = CreatePanelStripByProfile2(projId, cable.AssignedPanel, newTSSeq++, ioTypeOnC);
|
||||
if (newTS.Channels.Count() < setsSpared.Count + 1)//1代表至少要放一个set
|
||||
{
|
||||
//有问题了 panel的io模板,估计会导致无限循环了
|
||||
break;
|
||||
}
|
||||
matchedStrips.Add(newTS);
|
||||
}
|
||||
idx++; continue;// 需要下一个模块接着放本电缆
|
||||
// 手动递增索引,避免无限循环
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -909,50 +1184,32 @@ namespace Learun.Application.Web.AppApi
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 找到下一个可用的端子排
|
||||
/// 找到满足5%空闲通道的最大数
|
||||
/// </summary>
|
||||
/// <param name="setCount">电缆总set</param>
|
||||
/// <param name="TSs">所有的端子排</param>
|
||||
/// <param name="allUsedCH">使用过的channelId</param>
|
||||
/// <param name="ChCount">模块的所有通道数</param>
|
||||
/// <returns></returns>
|
||||
private ec_PanelStripEntity FindNextAvailableTS(int setCount,int setPreAssigned, List<ec_PanelStripEntity> TSs, List<string> allUsedCH)
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
static int FindMaxNumberChannel(int ChCount)
|
||||
{
|
||||
foreach (var TS in TSs)
|
||||
if (ChCount < 1)
|
||||
{
|
||||
var validChs = TS.Channels.Where(x => x.lock_flg == 0).ToList();//过滤掉锁定的通道
|
||||
var usedChs = validChs.Where(x => allUsedCH.Contains(x.ChannelID)).Select(x => x.ChannelID).ToList();
|
||||
var notUsedChs = validChs.Where(x => !usedChs.Contains(x.ChannelID)).ToList();
|
||||
|
||||
|
||||
double sparedRate = notUsedChs.Count * 1.0 / validChs.Count * 1.0;
|
||||
if (sparedRate < 0.05 || notUsedChs.Count < setPreAssigned)
|
||||
{
|
||||
//没有空闲通道 next
|
||||
//或者空闲通道不够放下这个电缆的所有set
|
||||
}
|
||||
else
|
||||
{
|
||||
TS.Channels = validChs.OrderBy(X => X.Channel_Seq).ToList();
|
||||
var seq = TSs.IndexOf(TS);
|
||||
|
||||
if (setCount > 10)
|
||||
{
|
||||
//另外如果电缆对数大于10对,即像12 * 2 * 0.75这种,无论它预分配了多少根电缆对,永远预留4个以下的空白通道。意思就是一个模块里面够4个或4个以上空白通道就留4个空白通道,如果不够4个就留4个以下即可。
|
||||
if (notUsedChs.Count < 4)
|
||||
{
|
||||
//没有足够的空闲通道 next
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return TS;//找到了
|
||||
}
|
||||
|
||||
|
||||
throw new ArgumentException("模块数量必须大于等于1", nameof(ChCount));
|
||||
}
|
||||
|
||||
// 从A-1开始向下寻找
|
||||
for (int i = 0; i < ChCount; i++)
|
||||
{
|
||||
// 检查是否大于5%
|
||||
if ((double)i / ChCount < 0.05 && (double)(i + 1) / ChCount > 0.05)
|
||||
{
|
||||
return ChCount - i;
|
||||
}
|
||||
}
|
||||
|
||||
return null;//都没有
|
||||
return ChCount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据step2的预分配结果,进行实际的分配,修改数据库。
|
||||
/// </summary>
|
||||
|
@ -148,7 +148,7 @@ namespace Learun.Application.TwoDevelopment.ZZDT_EC
|
||||
/// 是否被连接
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public bool? IsConned { set; get; }
|
||||
public bool? IsConned { set; get; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 当前这个set的连接情况
|
||||
@ -168,8 +168,7 @@ namespace Learun.Application.TwoDevelopment.ZZDT_EC
|
||||
#endregion
|
||||
|
||||
public ec_CableSetEntity()
|
||||
{
|
||||
IsConned = null;
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ namespace Learun.Application.TwoDevelopment.ZZDT_EC
|
||||
this.ChannelID = Guid.NewGuid().ToString();
|
||||
this.CreateTime = Time.MySqlTime;
|
||||
UserInfo userInfo = LoginUserInfo.Get();
|
||||
this.CreateUserID = userInfo.userId;
|
||||
this.CreateUserID = userInfo?.userId;
|
||||
|
||||
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ namespace Learun.Application.TwoDevelopment.ZZDT_EC
|
||||
this.StripID = Guid.NewGuid().ToString();
|
||||
this.CreateTime = Time.MySqlTime;
|
||||
UserInfo userInfo = LoginUserInfo.Get();
|
||||
this.CreateUserID = userInfo.userId;
|
||||
this.CreateUserID = userInfo?.userId;
|
||||
|
||||
|
||||
}
|
||||
@ -96,15 +96,23 @@ namespace Learun.Application.TwoDevelopment.ZZDT_EC
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public List<ec_PanelChannelEntity> Channels { set; get; } = new List<ec_PanelChannelEntity>();
|
||||
|
||||
/// <summary>
|
||||
/// channel在<see cref="ec_WireTerminalEntity"/>里有,同时<see cref="ec_Wire_GroupEntity.ChannelID"/>也有
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public int ChannelsUsed { set; get; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// channel在<see cref="ec_WireTerminalEntity"/>里有,但是没有信号
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public int ChannelsUsedNoSignal { set; get; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// channel在<see cref="ec_WireTerminalEntity"/>里没有
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public int ChannelsSpared { set; get; } = 0;
|
||||
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public string TagNumber { set; get; }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user