增加了homerun的分配逻辑(不需要考虑预留空白)

This commit is contained in:
xingheng 2025-10-01 23:35:57 +08:00
parent b8b6fde9b0
commit af328bdb8f

View File

@ -625,8 +625,10 @@ namespace Learun.Application.Web.AppApi
//1.2 流程图 分组原则为同一信号类型、同一系统的为一组
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 cNotPanel = cablesGrouped.FindAll(x => x.AssignedPanel == null);
cablesGrouped = cablesNeedAssigned.FindAll(x => x.AssignedPanel != null);
//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.AssignedPanel).Select(x => x.PanelID).Distinct().ToList();
@ -635,6 +637,15 @@ namespace Learun.Application.Web.AppApi
.Where(x => allPanelIds.Contains(x.PanelID))
.GroupBy(x => x.PanelID)
.ToDictionary(x => x.Key, x => x.ToList());//带出strip下的channel
foreach (var c in cNotPanel)
{
foreach (var set in c.Sets)
{
set.ConnectionInfo = "err没有找到合适的采集箱";
}
}
foreach (var curPanelId in allPanelIds)
{
int newTSSeq = 10001;
@ -645,11 +656,6 @@ namespace Learun.Application.Web.AppApi
var lastUsedStrip = (ec_PanelStripEntity)null;
foreach (var cable in cablesOnThisPanel)
{
if (cable.CableID == "8c8ebc52-1ae3-4074-af53-e914dd178e78")
{
Console.Write("");
}
;
//1.2.2 分组原则为同一信号类型、同一系统的为一组系统属性从电缆的from端上的设备中取设备的系统同组的优先放到同一个箱子的同一个模块里面
//如果一组放完后发现模块还有多余的通道可以放则下一个系统继续从这个模块开始分配。
//???总感觉这句话,总结后:可以无脑用上一个模块,直到模块满了再用下一个模块。
@ -659,7 +665,7 @@ namespace Learun.Application.Web.AppApi
//{
// sameGroup = false;//换组了
//}
#endregion
#endregion
//1.2 流程图 读取有提前选好箱子的信号
var setsSpared = cable.Sets.Where(x => string.IsNullOrEmpty(x.PreAssignGroup_Desc) || string.IsNullOrEmpty(x.PreAssignInOrOut)).ToList();
var setsIn = cable.Sets.Where(x => !string.IsNullOrEmpty(x.PreAssignGroup_Desc) && x.PreAssignInOrOut == SWS.Share.Enum.inOrOut..ToString()).ToList();
@ -669,8 +675,20 @@ namespace Learun.Application.Web.AppApi
if (cable.PreAssignIOType.ToLower() == GlobalEnum.signalType.Digital.ToString().ToLower())
{
if (setsIn.Count > 0 && setsOut.Count > 0) continue;
//from cjj 25 09 23 wechat:一根电缆可能会出现既有输入也有输出,如果碰到就放到两个端子排里面,公共端不会出现一个输出,一个输入的
if (setsIn.Count > 0 && setsOut.Count > 0)
{
foreach (var set in setsIn)
{
set.ConnectionInfo = "errdigital类型的电缆无法同时配置输入和输出。";
}
foreach (var set in setsOut)
{
set.ConnectionInfo = "errdigital类型的电缆无法同时配置输入和输出。";
}
continue;
//from cjj 25 09 23 wechat:一根电缆可能会出现既有输入也有输出,如果碰到就放到两个端子排里面,公共端不会出现一个输出,一个输入的
}
}
#endregion
@ -682,11 +700,23 @@ namespace Learun.Application.Web.AppApi
#endregion
#region output
if (setsOut.Count > 0)
else if (setsOut.Count > 0)
{
var resOut = AutoAssignCore(GlobalEnum.inOrOut., setsOut);
}
else
{
//all zero
foreach (var set in cable.Sets.Where(x => !setsSpared.Select(c => c.CableSetID).Contains(x.CableSetID)))
{
set.ConnectionInfo = "err信号描述为空";
}
foreach (var set in setsSpared)
{
set.ConnectionInfo = "err电缆无任一set被分配";
}
}
#endregion
@ -763,14 +793,7 @@ namespace Learun.Application.Web.AppApi
//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.32如果模块是通讯信号像RS485这种就是通讯信号则不用管预留空白通道这个事情看到有空的通道就放。
//当前这个端子排就是可用的
//
}
#region 1.2
//if (cable.Sets.Count > 10)
//{
@ -1012,77 +1035,106 @@ namespace Learun.Application.Web.AppApi
//被占用的(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)
{
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)
if (cable.CableClass.ToLower() == SWS.Share.Enum.cableClass.homerun.ToString())
{
//case1能顺利接完set还有多,还要再do循环一次,多余的set和spared都要放到下一个模块
NeedNextTS = true;
ChNeedConn = trueAvailableChs; SparedNeedConn = 0;
}
else if (trueAvailableChs == sets.Count)
{
//case3,刚好只有spared可能多
if (setsSpared.Count > 0)
//1.2.32如果模块是通讯信号像RS485这种就是通讯信号则不用管预留空白通道这个事情看到有空的通道就放。
if (allChCount < sets.Count)
{
//自己的感觉非客户word需求里的原话spared不能自己单独占用一个模块
//case1能顺利接完set还有多,还要再do循环一次,多余的set和spared都要放到下一个模块
NeedNextTS = true;
ChNeedConn = trueAvailableChs - 1;//留一个给spared
SparedNeedConn = 0;
ChNeedConn = allChCount; SparedNeedConn = 0;
}
else if (allChCount == sets.Count)
{
//case3,刚好只有spared可能多
ChNeedConn = allChCount;
SparedNeedConn = 0; //homerun不用考虑预留一个set去配合后续的spared
}
else
{
ChNeedConn = trueAvailableChs; SparedNeedConn = 0;
{
ChNeedConn = sets.Count;
SparedNeedConn = 0;
}
}
else
{
//maxCh > sets.Count
//case2,占满可用通道后或者没占满通道预分配set已经没了只剩下spared的set
if (setsSpared.Count == 0)
//1.2 流程图 空的通道数够不够
double sparedRate = notUsedChs.Count * 1.0 / allChCount * 1.0;
if (sparedRate < 0.05)
{
//ok
ChNeedConn = sets.Count; SparedNeedConn = 0;
}
//这种时候要确保spared也能放下
else if (trueAvailableChs < sets.Count + setsSpared.Count)
{
//自己的感觉非客户word需求里的原话spared不能自己单独占用一个模块
ChNeedConn = trueAvailableChs - 1;//留一个给spared
NeedNextTS = true;
SparedNeedConn = 0;
//同时又是最后一个了
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%
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
{
//ok,set和spared都能放下
ChNeedConn = sets.Count;
SparedNeedConn = setsSpared.Count;
//maxCh > sets.Count
//case2,占满可用通道后或者没占满通道预分配set已经没了只剩下spared的set
if (setsSpared.Count == 0)
{
//ok
ChNeedConn = sets.Count; SparedNeedConn = 0;
}
//这种时候要确保spared也能放下
else if (trueAvailableChs < sets.Count + setsSpared.Count)
{
//自己的感觉非客户word需求里的原话spared不能自己单独占用一个模块
ChNeedConn = sets.Count - 1;//留一个给spared
NeedNextTS = true;
SparedNeedConn = 0;
}
else
{
//ok,set和spared都能放下
ChNeedConn = sets.Count;
SparedNeedConn = setsSpared.Count;
}
}
}
//到这里,说明本模块至少都是可用的
TS.Channels = allCh.OrderBy(X => X.Channel_Seq).ToList();//不能像之前一样过滤掉,否则下一个电缆进来时,总数就不对了。
@ -1133,12 +1185,12 @@ namespace Learun.Application.Web.AppApi
#endregion
//shi否要继续
TS.ChannelsSpared = notUsedChs.Where(x=>x.lock_flg !=1).Count();
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);
@ -1150,10 +1202,10 @@ namespace Learun.Application.Web.AppApi
matchedStrips.Add(newTS);
}
idx++; continue;// 需要下一个模块接着放本电缆
// 手动递增索引,避免无限循环
// 手动递增索引,避免无限循环
}
else
{
{
break;
}
}