| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565 | using Aitex.Core.RT.DataCenter;using Aitex.Core.RT.Device;using Aitex.Core.RT.Fsm;using Aitex.Core.RT.Log;using Aitex.Core.RT.OperationCenter;using Aitex.Core.RT.SCCore;using Aitex.Core.Util;using CyberX8_RT.Devices.Facilities;using CyberX8_RT.Devices.Reservoir;using CyberX8_RT.Modules;using CyberX8_RT.Modules.Reservoir;using MECF.Framework.Common.CommonData.TemperatureControl;using MECF.Framework.Common.Device.TemperatureController;using MECF.Framework.Common.Persistent.Temperature;using MECF.Framework.Common.ToolLayout;using System;using System.Collections.Generic;using System.Linq;using System.Reflection;using System.Text;using System.Threading.Tasks;namespace CyberX8_RT.Devices.Temperature{    public class TemperatureController : BaseDevice, IDevice    {        #region 常量        private const string STRATUS = "Stratus";        private const string TARGET_TEMPERATURE = "TargetTemperature";        private const string RESERVIOR_TEMPERATURE = "ReserviorTemperature";        private const string HEAT_EXCHANGER_TEMPERATURE = "HeatExchangerTemperature";        private const string ALARM = "Alarm";        private const string OFFSET = "Offset";        private const string CONTROL_OPERATION_MODEL="ControlOperationModel";        private const string PB_RANGE = "PBRange";        private const string ARW_RANGE = "ARWRange";        private const string I_CONSTANT = "IConstant";        private const string D_CONSTANT = "DConstant";        private const string HEATING_POWER_UPPER_LIMIT = "HeatingPowerUpperLimit";        private const string COOLING_POWER_UPPER_LIMIT="CoolingPowerUpperLimit";        private const string OUT_PUT_RATIO="OutputRatio";        private const string TEMPERATURE_DATA = "TemperatureData";        private const string IS_CONNECTED = "IsConnected";        private const int ENABLE = 5;        private const int DISABLE = 0;        private const string PERSISTENT_VALUE = "PersistentValue";        #endregion        #region 内部变量        private byte _address;        private TemperatureControllerData _temperatureData = new TemperatureControllerData();        private PeriodicJob _periodicJob = null;        private bool _startMonitorData = false;        private bool _readAlarm = false;        private double _temeratureDeltaLimit = SC.GetValue<double>("System.TemeratureDelatLimit");        private bool _isApplying = false; //用于判断是否在apply中        private bool _isAlarmErrorLoged = false; //用于判断是否打印过alarm触发        private bool _isAlarmWarningLoged = false; //用于判断是否打印过alarm warning触发        private bool _isTCConnect = false;        /// <summary>        /// TC 持久性数值对象        /// </summary>        private TCPersistentValue _tCPersistentValue;        private Dictionary<int,string> _errorMessage = new Dictionary<int, string>         { { 3, " HighTempCutoff Property" },          { 2, " LowTempCutoff Property" },          { 1, " Fan Property" },          { 0, " OutputFailure Property" },          { 7, " TempLimitWarn Property" },          { 6, " RemoteOff Property" },          { 5, " Thermostat Property" },          { 4, " PowerFailure Property" },          { 11, " ExtSensorFailure Property" },          { 10, " IntSensorFailure Property" },          { 9, " AutoTuning Property" },          { 8, " Leak Property" }};        #endregion        #region 属性        /// <summary>        /// 连接状态        /// </summary>        public bool IsConnected { get { return TemperatureConfigManager.Instance.GetDeviceConnect(Module); } }        /// <summary>        /// 数据        /// </summary>        public TemperatureControllerData TemperatureData        {            get { return _temperatureData; }        }        #endregion        /// <summary>        /// 构造函数        /// </summary>;        /// <param name="moduleName"></param>        public TemperatureController(string moduleName) : base(moduleName, moduleName, moduleName, moduleName)        {            SubscribeValueAction();            InitializeData();            InitializeOperation();            _periodicJob = new PeriodicJob(5000, OnTimer, $"{moduleName}_reader");            _temperatureData.Name = $"{moduleName}";            _isAlarmErrorLoged = false;            _isAlarmWarningLoged = false;        }        /// <summary>        /// 初始化        /// </summary>        /// <returns></returns>        public bool Initialize()        {            TemperatureConfigManager.Instance.InitialDevice(Module);                        _periodicJob.Start();            return true;        }        /// <summary>        /// 初始化操作        /// </summary>        private void InitializeOperation()        {            OP.Subscribe($"{Module}.Apply", SetTargetTemperatureOperation);            OP.Subscribe($"{Module}.Enable", EnableOperation);            OP.Subscribe($"{Module}.Disable", DisableOperation);        }        /// <summary>        /// 监控TC电源        /// </summary>        /// <returns></returns>        private bool CheckTCIsConnect()        {            return TemperatureConfigManager.Instance.GetDevicePowerConnect(Module);        }        /// <summary>        /// 应用        /// </summary>        /// <param name="cmd"></param>        /// <param name="param"></param>        /// <returns></returns>        public bool SetTargetTemperatureOperation(string cmd,object[] param)        {            _isApplying = true; //表示正在调温            _temperatureData.HeatExchangerSeries = new List<double>();            _temperatureData.ReserviorSeries = new List<double>();            if (param.Length == 3 && double.TryParse(param[0].ToString(), out double targetTemperature) && double.TryParse(param[1].ToString(), out double targetTemperatureLowLimit) && double.TryParse(param[2].ToString(), out double targetTemperatureHighLimit))            {                TemperatureConfigManager.Instance.SetTargetTemperature(Module, _address, targetTemperature);                if (TemperatureData.ControlOperationModel == ENABLE)                {                    _startMonitorData = true;                }                //将前端输入的数据存入持久化文件                TCPersistentManager.Instance.UpdateTemperatureValue(Module, targetTemperature, targetTemperatureLowLimit, targetTemperatureHighLimit);                return true;            }            if (param.Length == 1 && double.TryParse(param[0].ToString(), out double targetTemperature1))            {                TemperatureConfigManager.Instance.SetTargetTemperature(Module, _address, targetTemperature1);                if (TemperatureData.ControlOperationModel == ENABLE)                {                    _startMonitorData = true;                }                //将前端输入的数据存入持久化文件                TCPersistentManager.Instance.UpdateTemperatureValue(Module, targetTemperature1, 0, 0); // 0 0是上下限                return true;            }            else            {                LOG.WriteLog(eEvent.INFO_TEMPERATURE, Module, $"{param[0]} is invalid");                return false;            }        }        /// <summary>        /// 启用        /// </summary>        /// <param name="cmd"></param>        /// <param name="param"></param>        /// <returns></returns>        public bool EnableOperation(string cmd, object[] param)        {            if (!JudgeReservoirCondition())            {                return false;            }            if (!CheckTCIsConnect())            {                LOG.WriteLog(eEvent.ERR_TEMPERATURE, Module, $"TC is not connect");                return false ;            }            //校验TC状态            if (TemperatureData.Alarm != null && TemperatureData.Alarm.Contains("1"))            {                string errorItemString = TemperatureData.Alarm.Substring(0, 11) + TemperatureData.Alarm.Substring(13, 1) + TemperatureData.Alarm.Substring(15);                if (errorItemString.Contains("1"))                {                    LOG.WriteLog(eEvent.ERR_TEMPERATURE, Module, $"TC is in error state");                    return false;                }            }            TemperatureData.ControlOperationModel = ENABLE;            bool result= TemperatureConfigManager.Instance.EnableControl(Module, _address,ENABLE);            if (result)            {                LOG.WriteLog(eEvent.INFO_TEMPERATURE, Module, "control operation set enable");                _startMonitorData = true;            }            return result;        }        /// <summary>        /// 禁用        /// </summary>        /// <param name="cmd"></param>        /// <param name="param"></param>        /// <returns></returns>        public bool DisableOperation(string cmd, object[] param)        {            _isApplying = false;            TemperatureData.ControlOperationModel = DISABLE;            bool result= TemperatureConfigManager.Instance.DisableController(Module, _address,DISABLE);            if(result)            {                if (result)                {                    ReservoirPostError();                    LOG.WriteLog(eEvent.INFO_TEMPERATURE, Module, "control operation set disable");                }                _startMonitorData = false;                if(TemperatureData.ReserviorSeries != null && TemperatureData.HeatExchangerSeries != null)                {                    _temperatureData.HeatExchangerSeries.Clear();                    _temperatureData.ReserviorSeries.Clear();                }            }            return result;        }        /// <summary>        /// Reservoir通知进入错误状态        /// </summary>        private void ReservoirPostError()        {            string reservoir = ReservoirItemManager.Instance.GetReservoirByTC(Module);            IModuleEntity reservoirEntity = Singleton<RouteManager>.Instance.GetModule<ReservoirEntity>(reservoir);            if (reservoirEntity != null)            {                if (!reservoirEntity.IsError && !reservoirEntity.IsDisable)                {                    reservoirEntity.PostMsg(ReservoirMsg.Error);                    LOG.WriteLog(eEvent.ERR_TEMPERATURE, Module, $"TC is abnormal,notify Reservoir {reservoir} enter error");                }            }        }        /// <summary>        /// 访问数据变更        /// </summary>        private void SubscribeValueAction()        {            TemperatureConfigManager.Instance.SubscribeModuleVariable(Module, TARGET_TEMPERATURE, UpdateVariableValue);            TemperatureConfigManager.Instance.SubscribeModuleVariable(Module, RESERVIOR_TEMPERATURE, UpdateVariableValue);            TemperatureConfigManager.Instance.SubscribeModuleVariable(Module, HEAT_EXCHANGER_TEMPERATURE, UpdateVariableValue);            TemperatureConfigManager.Instance.SubscribeModuleVariable(Module, ALARM, UpdateVariableValue);            TemperatureConfigManager.Instance.SubscribeModuleVariable(Module, OFFSET, UpdateVariableValue);            TemperatureConfigManager.Instance.SubscribeModuleVariable(Module, CONTROL_OPERATION_MODEL, UpdateVariableValue);            TemperatureConfigManager.Instance.SubscribeModuleVariable(Module, PB_RANGE, UpdateVariableValue);            TemperatureConfigManager.Instance.SubscribeModuleVariable(Module, ARW_RANGE, UpdateVariableValue);            TemperatureConfigManager.Instance.SubscribeModuleVariable(Module, I_CONSTANT, UpdateVariableValue);            TemperatureConfigManager.Instance.SubscribeModuleVariable(Module, D_CONSTANT, UpdateVariableValue);            TemperatureConfigManager.Instance.SubscribeModuleVariable(Module, OUT_PUT_RATIO, UpdateVariableValue);            TemperatureConfigManager.Instance.SubscribeModuleVariable(Module, HEATING_POWER_UPPER_LIMIT, UpdateVariableValue);            TemperatureConfigManager.Instance.SubscribeModuleVariable(Module, COOLING_POWER_UPPER_LIMIT, UpdateVariableValue);        }        /// <summary>        /// 初始化数据        /// </summary>        private void InitializeData()        {            _address= TemperatureConfigManager.Instance.GetAddress(Module);            _tCPersistentValue = TCPersistentManager.Instance.GetTCPersistentValue(Module);            DATA.Subscribe($"{Module}.{TEMPERATURE_DATA}", () => _temperatureData, SubscriptionAttribute.FLAG.IgnoreSaveDB);            DATA.Subscribe($"{Module}.{IS_CONNECTED}", () => _isTCConnect, SubscriptionAttribute.FLAG.IgnoreSaveDB);            DATA.Subscribe($"{Module}.{PERSISTENT_VALUE}", () => _tCPersistentValue, SubscriptionAttribute.FLAG.IgnoreSaveDB);            DATA.Subscribe($"{Module}.TargetTemperature", () => _temperatureData.TargetTemperature, SubscriptionAttribute.FLAG.IgnoreSaveDB);            DATA.Subscribe($"{Module}.Status", () => _temperatureData.Status, SubscriptionAttribute.FLAG.IgnoreSaveDB);            DATA.Subscribe($"{Module}.Alarm", () => _temperatureData.Alarm, SubscriptionAttribute.FLAG.IgnoreSaveDB);            DATA.Subscribe($"{Module}.ReserviorTemperature", () => _temperatureData.ReserviorTemperature, SubscriptionAttribute.FLAG.IgnoreSaveDB);            DATA.Subscribe($"{Module}.HeatExchangerTemperature", () => _temperatureData.HeatExchangerTemperature, SubscriptionAttribute.FLAG.IgnoreSaveDB);        }        /// <summary>        /// 更新变量数值        /// </summary>        /// <param name="variable"></param>        /// <param name="value"></param>        private void UpdateVariableValue(string variable, object value)        {            if(!TemperatureData.IsInitialized)            {                TemperatureData.IsInitialized = true;                TemperatureConfigManager.Instance.ReadControlOperationModel(Module, _address);                TemperatureConfigManager.Instance.ReadTargetTemperature(Module, _address);            }            PropertyInfo property = TemperatureData.GetType().GetProperty(variable);            if (property != null)            {                property.SetValue(TemperatureData, value);            }            //判断temperatureReached AtTemperatureRange            double atTemperatureRange = SC.GetValue<double>("System.AtTemperatureRange");            atTemperatureRange = atTemperatureRange == 0 ? 0.1 : atTemperatureRange;            if (Math.Abs(TemperatureData.ReserviorTemperature - TemperatureData.TargetTemperature) < atTemperatureRange)            {                TemperatureData.TemperatureReached = true;                //_startMonitorData = false;               }            else            {                TemperatureData.TemperatureReached = false;            }            //判断deltaexceed            if (Math.Abs(TemperatureData.ReserviorTemperature - TemperatureData.ReserviorTemperature) > _temeratureDeltaLimit)            {                TemperatureData.DeltaExceed = true;            }            else            {                TemperatureData.DeltaExceed = false;            }            if (_startMonitorData && TemperatureData.ReserviorSeries!=null && TemperatureData.HeatExchangerSeries!=null)            {                if (TemperatureData.ReserviorSeries.Count == 20)                {                    TemperatureData.ReserviorSeries.RemoveAt(0);                    for (int i = 1; i < TemperatureData.ReserviorSeries.Count; i++)                    {                        TemperatureData.ReserviorSeries[i - 1] = TemperatureData.ReserviorSeries[i];                    }                    TemperatureData.ReserviorSeries.Add(TemperatureData.ReserviorTemperature);                }                else                {                    TemperatureData.ReserviorSeries.Add(TemperatureData.ReserviorTemperature);                }                if (TemperatureData.HeatExchangerSeries.Count == 20)                {                    TemperatureData.HeatExchangerSeries.RemoveAt(0);                    for (int i = 1; i < TemperatureData.HeatExchangerSeries.Count; i++)                    {                        TemperatureData.HeatExchangerSeries[i - 1] = TemperatureData.HeatExchangerSeries[i];                    }                    TemperatureData.HeatExchangerSeries.Add(TemperatureData.HeatExchangerTemperature);                }                else                {                    TemperatureData.HeatExchangerSeries.Add(TemperatureData.HeatExchangerTemperature);                }            }        }        /// <summary>        /// 定时器        /// </summary>        /// <returns></returns>        private bool OnTimer()        {            _isTCConnect = CheckTCIsConnect();            if (!_isTCConnect)            {                string reservoir = ReservoirItemManager.Instance.GetReservoirByTC(Module);                if (!string.IsNullOrEmpty(reservoir))                {                    ReservoirEntity reservoirEntity = Singleton<RouteManager>.Instance.GetModule<ReservoirEntity>(reservoir);                    if(reservoirEntity != null && !reservoirEntity.IsError)                     {                        LOG.WriteLog(eEvent.ERR_TEMPERATURE, Module, $"{Module} is disconnect,releate reservoir into error");                        reservoirEntity.PostMsg(ReservoirMsg.Error);                    }                }            }            TemperatureConfigManager.Instance.ReadReserviorExtendSensorTemperature(Module, _address);            TemperatureConfigManager.Instance.ReadHeatExchangerInternelSensorTemperature(Module, _address);            if (_readAlarm)            {                TemperatureConfigManager.Instance.ReadAlarmStatus(Module, _address);                _readAlarm= false;            }            else            {                _readAlarm = true;            }            double rampStepSize = SC.GetValue<double>("System.RampStepSize");            rampStepSize = rampStepSize == 0 ? 0.11 : rampStepSize;            if (TemperatureData.TargetTemperature - TemperatureData.ReserviorTemperature > rampStepSize + 0.1 && _isApplying == true)            {                TemperatureData.Status = "RampingUp";            }            else if(TemperatureData.TargetTemperature - TemperatureData.ReserviorTemperature < -rampStepSize - 0.1 && _isApplying == true)            {                TemperatureData.Status = "RampingDown";            }            else if (TemperatureData.TargetTemperature - TemperatureData.ReserviorTemperature <= rampStepSize + 0.1 && TemperatureData.TargetTemperature - TemperatureData.ReserviorTemperature >= - rampStepSize - 0.1 && _isApplying == true)            {                TemperatureData.Status = "Maintaining";            }            else if(TemperatureData.Alarm!=null&&TemperatureData.Alarm.Contains("1"))            {                string errorItemString = TemperatureData.Alarm.Substring(0, 11) + TemperatureData.Alarm.Substring(13, 1) + TemperatureData.Alarm.Substring(15);                if (TemperatureData.Alarm.Substring(12,1) == "1" || TemperatureData.Alarm.Substring(14, 1)== "1")                {                    TemperatureData.Status = "Warning";                    if (!_isAlarmWarningLoged)                    {                        LOG.WriteLog(eEvent.WARN_TEMPERATURE, Module, $"{Module} Warning is activate");                        _isAlarmWarningLoged = true;                    }                }                if(errorItemString.Contains("1"))                {                    if (!_isAlarmErrorLoged)                    {                        string errormessage = "";                        string[] strAry = TemperatureData.Alarm.ToString().Split('-');                        if (strAry.Length > 0)                        {                            for (int i = 0; i < strAry.Length; i++)                            {                                if (strAry[i] == "1")                                {                                    errormessage += _errorMessage[i];                                }                            }                        }                        LOG.WriteLog(eEvent.ERR_TEMPERATURE, Module, $"{Module} {errormessage} is activate");                        ReservoirPostError();//将对应的reservoir切成error                        _isAlarmErrorLoged = true;                    }                }            }            else            {                TemperatureData.Status = "Normal";                _isAlarmErrorLoged = false;  //用于控制触发alarm要不要打印error日志                _isAlarmWarningLoged = false;  //用于控制触发alarm要不要打印error日志            }            if (TemperatureData.ControlOperationModel != 0)            {                if (!JudgeReservoirCondition())                {                    DisableOperation("", null);                }            }            if (TemperatureData.Alarm!=null && TemperatureData.Alarm.Contains("1") && _isApplying == true)            {                string errorItemString = TemperatureData.Alarm.Substring(0, 11) + TemperatureData.Alarm.Substring(13, 1) + TemperatureData.Alarm.Substring(15);                if (errorItemString.Contains("1"))                {                    DisableOperation("", null);                    string errormessage = "";                    string[] strAry = errorItemString.ToString().Split('-');                    if (strAry.Length > 0)                    {                        for (int i = 0; i < strAry.Length; i++)                        {                            if (strAry[i] == "1")                            {                                errormessage += _errorMessage[i];                            }                        }                    }                    ReservoirPostError();//将对应的reservoir切成error                    LOG.WriteLog(eEvent.ERR_TEMPERATURE, Module, $"{Module} {errormessage} is activate");                    _isApplying = false;                }                            }            return true;        }        /// <summary>        /// 检验Reservoir条件        /// </summary>        private bool JudgeReservoirCondition()        {            SystemFacilities systemFacilities = DEVICE.GetDevice<SystemFacilities>("System.Facilities");            if (systemFacilities == null)             {                return false;            }            //冷却水没开            if (!systemFacilities.HouseChilledWaterEnable)            {                LOG.WriteLog(eEvent.ERR_TEMPERATURE, Module, "Facilities HouseChilledWaterEnable is off");                return false;            }            var houseChilledResult = systemFacilities.CheckHouseChilledWaterResult();            if (!houseChilledResult.result)            {                LOG.WriteLog(eEvent.ERR_TEMPERATURE, Module, houseChilledResult.reason);                return false;            }            string reservoir = ReservoirItemManager.Instance.GetReservoirByTC(Module);            if (string.IsNullOrEmpty(reservoir))            {                LOG.WriteLog(eEvent.ERR_TEMPERATURE, Module, $"{Module} reservoir is empty");                return false;            }            ReservoirItem reservoirItem = ReservoirItemManager.Instance.GetReservoirItem(reservoir);            if (reservoirItem.SubType == STRATUS)            {                StandardHotReservoirDevice reservoirDevice = DEVICE.GetDevice<StandardHotReservoirDevice>(reservoir);                if (reservoirDevice == null)                {                    LOG.WriteLog(eEvent.ERR_TEMPERATURE, Module, $"{Module} reservoir is null");                    return false;                }                bool result= reservoirDevice.ReservoirData.HedFlow > 0;                if (!result)                {                    LOG.WriteLog(eEvent.ERR_TEMPERATURE, Module, $"{Module} reservoir HED flow is 0");                }                return result;            }            else            {                CompactMembranReservoirDevice reservoirDevice = DEVICE.GetDevice<CompactMembranReservoirDevice>(reservoir);                if (reservoirDevice == null)                {                    LOG.WriteLog(eEvent.ERR_TEMPERATURE, Module, $"{Module} reservoir is null");                    return false;                }                bool result = reservoirDevice.ReservoirData.CAHedFlow > 0;                if (!result)                {                    LOG.WriteLog(eEvent.ERR_TEMPERATURE, Module, $"{Module} reservoir CA HED flow is 0");                }                return result;            }        }        /// <summary>        /// 设置Enable并设置温度        /// </summary>        /// <param name="targetTemperature"></param>        /// <returns></returns>        public bool SetEnableTargetTemperature(double targetTemperature)        {            TemperatureConfigManager.Instance.SetTargetTemperature(Module, _address, targetTemperature);            if (_temperatureData.ControlOperationModel == DISABLE)            {                EnableOperation("", null);            }            return true;        }        /// <summary>        /// 监控        /// </summary>        public void Monitor()        {        }        public void Reset()        {        }        public void Terminate()        {        }    }}
 |