using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.ComponentModel;
using FLY.FeedbackRenZiJia.IService;
using FLY.FeedbackRenZiJia.Common;
using PropertyChanged;
namespace FLY.FeedbackRenZiJia.Server
{
///
/// 加热棒检测
///
class HeatCheck:IHeatCheck,INotifyPropertyChanged
{
const int HEAT_WAIT = 3;//3s
HeatCell mHeatCell;
enum CHECK_MODE
{
///
/// 什么都不干
///
IDLE,
///
/// 当前0输出,检测电流是否为0
///
CHECK_ZERO,
///
/// 当前有输出, 电流不应该为0
///
CHECK_NOZERO,
///
/// 检测每根加热棒
///
CHECK_EVERYONE
}
CHECK_MODE checkMode = CHECK_MODE.IDLE;
int counter = 0;
#region IHeatCheck
///
/// 有这个功能
///
public bool Has { get; set; }
///
/// 动作使能
///
public bool Enable { get; set; }
///
/// 有电流
///
public bool HasElectricity { get; set; }
///
/// 当前正在检测的加热棒号, 1~88
///
public int CheckNo { get; set; }
///
/// 当前检测的阶段
///
public int CheckStep { get; set; }
#region 根据电流判断的加热棒状态
///
/// 加热棒是好的,但电流小,必须两条同时加热才可以。
///
private int HalfIdx;
private List maybeIdx = new List();
///
/// 坏的加热棒
///
[DoNotCheckEquality]
public bool[] Bads { get; set; }
///
/// 没加热,也有电流, 电路板短路了
///
public bool ShortCircuit { get; set; }
///
/// 没有上电, 或者电流计坏了
///
public bool PowerOff { get; set; }
///
/// 有加热棒断路了
///
public bool OpenCircuit { get; set; }
#endregion
#endregion
public void Init(HeatCell heatCell)
{
mHeatCell = heatCell;
FObjBase.PollModule.Current.Poll_Config(FObjBase.PollModule.POLL_CONFIG.ADD, OnPoll, TimeSpan.FromSeconds(1));
Init();
Load();
mHeatCell.PropertyChanged += new PropertyChangedEventHandler(mHeatCell_PropertyChanged);
this.PropertyChanged += HeatCheck_PropertyChanged;
}
private void HeatCheck_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Enable")
{
if (Enable)
Start();
else
Stop();
}
}
void mHeatCell_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "ChannelCnt")
{
Init();
Load();
}
}
void Init()
{
Bads = new bool[mHeatCell.ChannelCnt];
OpenCircuit = false;
PowerOff = false;
ShortCircuit = false;
}
///
/// 启动
///
void Start()
{
checkMode = CHECK_MODE.CHECK_EVERYONE;
CheckStep = 0;
counter = 0;
Array.Clear(Bads, 0, Bads.Count());
NotifyPropertyChanged("Bads");
OpenCircuit = false;
PowerOff = false;
ShortCircuit = false;
}
///
/// 停止
///
void Stop()
{
checkMode = CHECK_MODE.IDLE;
//清空全部加热
mHeatCell.ClearPreHeats();
mHeatCell.HeatApply();
//保存Bads
Save();
}
void Load()
{
string path = "bads.xml";
FeedbackHeatsMark mark = FeedbackHeatsMark.Load(path);
if ((mark != null) && (mark.heats != null))
{
for (int i = 0; i < Bads.Count() ; i++)
{
if (i < mark.heats.Count())
Bads[i] = ((mark.heats[i] == 0) ? false : true);
else
Bads[i] = false;
}
NotifyPropertyChanged("Bads");
OpenCircuit = Bads.Any(b => b);
}
}
void Save()
{
string path = "bads.xml";
FeedbackHeatsMark mark = new FeedbackHeatsMark();
mark.heats = (from b in Bads select (b) ? 1 : 0).ToArray();
mark.Save(path);
}
void OnPoll()
{
switch (checkMode)
{
case CHECK_MODE.CHECK_EVERYONE:
OnPoll_Check();
break;
default:
OnPoll_Normal();
break;
}
}
///
/// 平常,测有没电流
///
void OnPoll_Normal()
{
if (!Has)
return;
if (mHeatCell.Heats.All(h => h == 0))//没有加热,不应该有电流
{
if (checkMode != CHECK_MODE.CHECK_ZERO) //第1次
{
checkMode = CHECK_MODE.CHECK_ZERO;
counter = 0;
}
//先等待3秒,3秒后再判断
counter++;
if (counter > 5)
{
counter = 0;
if (HasElectricity)//有电流,有问题
{
ShortCircuit = true;
}
else
{
ShortCircuit = false;
}
}
}
else
{
if (checkMode != CHECK_MODE.CHECK_NOZERO) //第1次
{
checkMode = CHECK_MODE.CHECK_NOZERO;
counter = 0;
}
if (HasElectricity)
{
counter = 0;
PowerOff = false;
}
else
{
counter++;
if (counter > 7)//连续7秒,都没有一秒有电流,没有上电
{
PowerOff = true;
counter = 0;
}
}
}
}
///
/// 加热棒检测周期
///
void OnPoll_Check()
{
switch (CheckStep)
{
case 0://刚按了开始,清空,检查应该没电流才对
{
if (counter == 0)
{
mHeatCell.ClearPreHeats();
mHeatCell.HeatApply();
counter++;
}
else if (counter < HEAT_WAIT)
{
counter++;
}
else//3秒后
{
if (HasElectricity)
{
ShortCircuit = true;//没输出,也有电流,板烧了
Enable = false;//停止检测
return;
}
CheckStep++;
counter = 0;
}
}break;
case 1://全部加热30%
{
if (counter == 0)
{
mHeatCell.ModifyPreHeats(getAllHeat_30(mHeatCell.ChannelCnt));
mHeatCell.HeatApply();
counter++;
}
else if (counter < HEAT_WAIT)
{
if (HasElectricity)
{
//有上电!!!
//正式开始
CheckStep++;
counter = 0;
break;
}
counter++;
}
else//3秒内,都没1秒有电,不正常,应该是没上电
{
PowerOff = true;
Enable = false;//停止检测
return;
}
}break;
case 2://正式开始
{
if (counter == 0)
{
CheckNo = 1;
mHeatCell.ModifyPreHeats(getSingleHeat_100(mHeatCell.ChannelCnt, CheckNo - 1));
mHeatCell.HeatApply();
counter = 1;
}
else if (counter < HEAT_WAIT)
{
counter++;
}
else
{
//3秒后
if (!HasElectricity)//这个位没电流,可能是坏了,还需要2次检查
{
Bads[CheckNo - 1] = true;
NotifyPropertyChanged("Bads");
OpenCircuit = true;
}
if (CheckNo < mHeatCell.ChannelCnt)
{
CheckNo++;
mHeatCell.ModifyPreHeats(getSingleHeat_100(mHeatCell.ChannelCnt, CheckNo - 1));
mHeatCell.HeatApply();
counter = 1;
}
else
{
//检查是否2次检测
int cnt = Bads.Count((b) => { return b; });
if (cnt <2)
{
//没有坏,或只有一条加热棒坏了,没法2次检测
//完成
Enable = false;//停止检测
return;
}
else
{
//需要2次检测
CheckStep++;
counter = 0;
}
}
}
}
break;
case 3://2次检测
{
if (counter == 0)//刚进入!!!
{
HalfIdx = -1;//可能坏的加热棒中,还没有一条是好的
for (int i = 0; i < Bads.Count(); i++)//登记全部坏的加热棒
{
if (Bads[i])
{
maybeIdx.Add(i);
}
}
CheckNo = maybeIdx.First() + 1;//当前检测的位置,现在没用!!!
//肯定有2条加热棒是坏了,不用检测maybeIdx.Count()
mHeatCell.ModifyPreHeats(getSingleHeat_100(mHeatCell.ChannelCnt,
maybeIdx[0],
maybeIdx[1]));
mHeatCell.HeatApply();
counter = 1;
}
else if (counter < HEAT_WAIT)//3秒延时
{
counter++;
}
else//3秒后
{
if (!HasElectricity)//没电流,肯定是坏了
{
if (HalfIdx < 0)//还没有一个 "肯定是好的,只是电流不够的加热棒"
{
maybeIdx.RemoveRange(0, 2);//之前测试的两条肯定是坏的,不用再查了(这个有bug的)
if (maybeIdx.Count() <= 1)
{
//只剩下一个,没法检测结束
Enable = false;//停止检测
return;
}
}
else
{
//已经有 好的!!!, 刚才测的那条肯定是坏的
maybeIdx.RemoveAt(0);
if (maybeIdx.Count() == 0)
{
//全部检测完了
Enable = false;//停止检测
return;
}
}
CheckNo = maybeIdx[0] + 1;
int idx1 = (HalfIdx >= 0) ? HalfIdx : maybeIdx[1];
mHeatCell.ModifyPreHeats(getSingleHeat_100(mHeatCell.ChannelCnt,
maybeIdx[0],
idx1));
mHeatCell.HeatApply();
counter = 1;
}
else
{
//刚才测量的是好的!!!!!
if (HalfIdx < 0)//还没有一个 "肯定是好的,只是电流不够的加热棒"
{
Bads[maybeIdx[0]] = false;//清除坏的记录
Bads[maybeIdx[1]] = false;
HalfIdx = maybeIdx[0];//登记其中一条好的加热棒
maybeIdx.RemoveRange(0, 2);
}
else
{
Bads[maybeIdx[0]] = false;//清除坏的记录
maybeIdx.RemoveAt(0);
}
NotifyPropertyChanged("Bads");
OpenCircuit = Bads.Any(b => b);
if (maybeIdx.Count() <= 0)
{
//一个都不剩,完成
Enable = false;//停止检测
return;
}
CheckNo = maybeIdx[0] + 1;
mHeatCell.ModifyPreHeats(getSingleHeat_100(mHeatCell.ChannelCnt,
maybeIdx[0],
HalfIdx));
mHeatCell.HeatApply();
counter = 1;
}
}
}break;
}
}
int[] getSingleHeat_100(int channelcnt, params int[] index)
{
int[] heats = new int[channelcnt];
Array.Clear(heats, 0, heats.Count());
foreach(int i in index)
heats[i] = 100;
return heats;
}
int[] getSingleHeat_100(int channelcnt, int index)
{
int[] heats = new int[channelcnt];
Array.Clear(heats, 0, heats.Count());
heats[index] = 100;
return heats;
}
int[] getAllHeat_30(int channelcnt)
{
int[] heats = new int[channelcnt];
for (int i = 0; i < heats.Count(); i++)
{
heats[i] = 30;
}
return heats;
}
#region INotifyPropertyChanged 成员
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyname)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
#endregion
}
}