using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading;
using EntityDataSet;
using IntelligentControlForsx.Service.WindturbineControl.Domain.Cmd;
namespace IntelligentControlForsx.Service.WindturbineControl.IntPtrSvc
{
public class ControlSvc
{
private static ControlSvc svc = new ControlSvc();
private ControlSvc()
{
}
public static ControlSvc GetControlSvc()
{
return svc;
}
///
/// 发送控制指令--1.5MW机型
///
/// 控制句柄
/// 控制信息集合
/// 发送失败的集合
/// 发送成功的风机Id集合
public static IList SendCmd_Up82(IntPtr intPtr, IList cmdList, out IList faultSendList)
{
byte[] typeArr = cmdList.Select(s => (byte)s.ControlType).ToArray();
uint[] addressArr = cmdList.Select(s => (uint)s.CmdId).ToArray();
float[] valueArr = cmdList.Select(s => s.CmdValue).ToArray();
int count = CmdSendService.gycp_control(intPtr, typeArr, addressArr, valueArr, (uint)addressArr.Length);
//获取发送失败的风机Id集合
faultSendList = GetSendFaultWindtrubineIds();
//收集并返回发送成功的风机Id集合
IList fault = faultSendList;
return cmdList.Where(s => !fault.Contains(s.WindturbineId)).Select(k => k.WindturbineId).ToList();
}
///
/// 发送控制指令2MW机型
///
/// 控制句柄
/// 控制信息集合
/// 发送失败的集合
/// 送成功的风机Id集合
public static IList SendCmd_Up105(IntPtr intPtr, IList cmdList, out IList faultSendList)
{
/*
* 停机操作:停机地址发送1,停机地址发送0
* 启动操作:复位地址发送1,复位地址发送0
*/
byte[] typeArr = cmdList.Select(s => (byte)s.ControlType).ToArray();
uint[] addressArr = cmdList.Select(s => (uint)s.CmdId).ToArray();
float[] valueArr1 = cmdList.Select(s => s.CmdValue).ToArray();
float[] valueArr0 = cmdList.Select(s => s.CmdValue).ToArray();
int count1 = CmdSendService.gycp_control(intPtr, typeArr, addressArr, valueArr1, (uint)addressArr.Length);
IList faultSend1 = GetSendFaultWindtrubineIds();
Thread.Sleep(800);
int count0 = CmdSendService.gycp_control(intPtr, typeArr, addressArr, valueArr0, (uint)addressArr.Length);
IList faultSend0 = GetSendFaultWindtrubineIds();
//将两次发送的命令失败集合合并(并集)并去重
faultSendList = faultSend1.Union(faultSend0).ToList().Distinct().ToList();
//收集并返回发送成功的风机Id集合
IList fault = faultSendList;
return cmdList.Where(s => !fault.Contains(s.WindturbineId)).Select(k => k.WindturbineId).ToList();
}
///
/// 根据风机编号及其操作类型发送操作指令
///
/// 风机编号集合
/// 风场编号
/// 操作类型
/// 指令发送失败的风机集合
/// 控制描述(手动,执行推荐)
/// 操作人
/// 控制指令是否全部发送成功
public bool SendCmdByWindturbineIdList(IList windturbinList, string stationId, CmdType cmdType, out IList faultSendList, string description, user user)
{
faultSendList = new List();
using (wisdom_cs_entity ctx = new wisdom_cs_entity())
{
IList list =
ctx.windturbine.Where(s => windturbinList.Contains(s.ID) && s.WINDPOWERSTATIONID == stationId)
.ToList();
IList controlInfoListUp82 = new List();
IList cmdInfoListUp82 = new List();
IList controlInfoListUp105 = new List();
IList cmdInfoListUp105 = new List();
for (int i = 0; i < list.Count; i++)
{
if (list[i].MODELID != "UP105-2000-S")
{
#region 操控记录实体
control_info info = new control_info();
info.control_description = description;
info.user_id = user.id;
info.time = DateTime.Now;
info.success_time = null;
info.windturbine_id = list[i].ID;
info.type = (int)cmdType;
controlInfoListUp82.Add(info);
#endregion
#region 风机命令实体
WindturbineCmdInfo cmdInfo = new WindturbineCmdInfo();
if (list[i].GYCP_ID.HasValue)
cmdInfo.CmdIntPtr = ControlIntPtr.dic[list[i].PROJECTID];
cmdInfo.WindturbineId = list[i].ID;
cmdInfo.CmdType = cmdType;
cmdInfo.ControlType = CmdSendService.GYCP_TYPE_YK;
int controlType = 0;
if (cmdInfo.CmdType == CmdType.Start)
controlType = 1; //启动
else if (cmdInfo.CmdType == CmdType.Stop)
controlType = 2; //停机
else if (cmdInfo.CmdType == CmdType.Maintain)
controlType = 3; //维护
else if (cmdInfo.CmdType == CmdType.UnMaintain)
controlType = 4; //取消维护
else if (cmdInfo.CmdType == CmdType.Reset)
controlType = 5; //复位
//获取控制点
string windturbineId = list[i].ID;
gycp_cmd_info gycpCmdInfo =
ctx.gycp_cmd_info.Where(
s => s.type == controlType && s.windturbine_id == windturbineId)
.FirstOrDefault();
//获取控制地址
gycp_address address = null;
if (list[i].GYCP_ID.HasValue)
{
int gycpId = list[i].GYCP_ID.Value;
address = ctx.gycp_address.Where(s => s.id == gycpId).FirstOrDefault();
}
if (address != null && gycpCmdInfo != null)
{
cmdInfo.CmdId = gycpCmdInfo.cmd_id;
if (gycpCmdInfo.cmd_value.HasValue)
cmdInfo.CmdValue = gycpCmdInfo.cmd_value.Value;
}
cmdInfo.UserId = user.id;
cmdInfo.Time = DateTime.Now;
cmdInfo.IsSuccessSend = false;
cmdInfoListUp82.Add(cmdInfo);
#endregion
}
else
{
#region 操控记录实体
control_info info = new control_info();
info.control_description = description;
info.user_id = user.id;
info.time = DateTime.Now;
info.success_time = null;
info.windturbine_id = list[i].ID;
info.type = (int)cmdType;
controlInfoListUp105.Add(info);
#endregion
#region 风机命令实体
WindturbineCmdInfo cmdInfo = new WindturbineCmdInfo();
if (list[i].GYCP_ID.HasValue)
cmdInfo.CmdIntPtr = ControlIntPtr.dic[list[i].PROJECTID];
cmdInfo.WindturbineId = list[i].ID;
cmdInfo.CmdType = cmdType;
cmdInfo.ControlType = CmdSendService.GYCP_TYPE_YK;
int controlType = 0;
if (cmdInfo.CmdType == CmdType.Start)
controlType = 5; //启动
else if (cmdInfo.CmdType == CmdType.Stop)
controlType = 1; //停机
//获取控制点
string windturbineId = list[i].ID;
gycp_cmd_info gycpCmdInfo =
ctx.gycp_cmd_info.Where(
s => s.type == controlType && s.windturbine_id == windturbineId)
.FirstOrDefault();
//获取控制地址
gycp_address address = null;
if (list[i].GYCP_ID.HasValue)
{
int gycpId = list[i].GYCP_ID.Value;
address = ctx.gycp_address.Where(s => s.id == gycpId).FirstOrDefault();
}
if (address != null && gycpCmdInfo != null)
{
cmdInfo.CmdId = gycpCmdInfo.cmd_id;
if (gycpCmdInfo.cmd_value.HasValue)
cmdInfo.CmdValue = gycpCmdInfo.cmd_value.Value;
}
cmdInfo.UserId = user.id;
cmdInfo.Time = DateTime.Now;
cmdInfo.IsSuccessSend = false;
cmdInfoListUp105.Add(cmdInfo);
#endregion
}
}
var groupResultUp82 = cmdInfoListUp82.GroupBy(x => x.CmdIntPtr);
foreach (var info in groupResultUp82)
{
IList falutList = new List();
List itemList = info.ToList();
IList successWindturbineIdList = SendCmd_Up82(itemList[0].CmdIntPtr, itemList, out falutList);
#region 保存命令执行成功的记录
IList successList =
controlInfoListUp82.Where(s => successWindturbineIdList.Contains(s.windturbine_id)).ToList();
for (int i = 0; i < successList.Count; i++)
{
ctx.Entry(successList[i]).State = EntityState.Added;
ctx.SaveChanges();
}
#endregion
faultSendList = faultSendList.Union(falutList).ToList();//收集命令发送失败的风机集合
}
var groupResultUp105 = cmdInfoListUp105.GroupBy(x => x.CmdIntPtr);
foreach (var info in groupResultUp105)
{
IList falutList = new List();
List itemList = info.ToList();
IList successWindturbineIdList = SendCmd_Up105(itemList[0].CmdIntPtr, itemList, out falutList);
#region 保存命令执行成功的记录
IList successList =
controlInfoListUp105.Where(s => successWindturbineIdList.Contains(s.windturbine_id)).ToList();
for (int i = 0; i < successList.Count; i++)
{
ctx.Entry(successList[i]).State = EntityState.Added;
ctx.SaveChanges();
}
#endregion
faultSendList = faultSendList.Union(falutList).ToList();//收集命令发送失败的风机集合
}
if (faultSendList.Count <= 0)
return true;
else
return false;
}
}
///
/// 根据回调函数返回的数据得到命令发送失败的风机Id集合
///
///
public static IList GetSendFaultWindtrubineIds()
{
IList list = new List();
ControlResult result = ControlIntPtr.result;
if (result != null)
{
for (int i = 0; i < result.Errors.Length; i++)
{
//错误值为1时代表发送失败
if (result.Errors[i] == 1)
{
using (wisdom_cs_entity ctx = new wisdom_cs_entity())
{
gycp_cmd_info info =
ctx.gycp_cmd_info.Where(s => s.cmd_id == result.Addresses[i]).FirstOrDefault();
if (info != null)
list.Add(info.windturbine_id);
}
}
}
ControlIntPtr.result = new ControlResult();
}
return list;
}
}
}