Sic.Framework-Nanjing-Baishi/MECF.Framework.RT.Equipment.../HardwareUnits/UPS/ITAUPS.cs

356 lines
11 KiB
C#
Raw Normal View History

2023-04-13 11:51:03 +08:00
using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Device.Devices;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.IOCore;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using MECF.Framework.Common.Communications;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.UPS
{
public class ITAUPS : BaseDevice, IConnection, IDevice
{
private ITAUPSConnection _connection;
private bool _activeMonitorStatus;
private int _errorCode;
private R_TRIG _trigRetryConnect = new R_TRIG();//断开上升沿
private R_TRIG _trigReconnection = new R_TRIG();//重连上升沿
private R_TRIG _trigPowerLow = new R_TRIG();//缺电上升沿
private PeriodicJob _thread;
private int tempCount = 1;
private LinkedList<HandlerBase> _lstHandler = new LinkedList<HandlerBase>();
private object _locker = new object();
private bool _enableLog = true;
private string _scRoot;
private string portName;
private string _systemStatus;
private float _inputVoltage;
private float _batteryVoltage;
private float _batteryRemainsTime;
private float _batteryUnderResidue;
public string SystemStatus { get; set; }
public float InputVoltage { get; set; }
public float BatteryVoltage { get; set; }
public float BatteryRemainsTime { get; set; }
public float BatteryUnderResidue { get; set; }
public bool UPSPowerAlarm { get; set; }
public bool UPSLowerBatteryAlarm { get; set; }
public int ErrorNum { get; set; } = 0;
public string Address
{
get; set;
}
public bool IsConnected
{
get
{
return _connection != null && _connection.IsConnected;
}
}
public bool Connect()
{
return true;
}
public bool Disconnect()
{
_connection.Disconnect();
return true;
}
public ITAUPS(string module, string name, string scRoot, DOAccessor BatteryLowVoltage, DOAccessor UpsEnable) : base(module, name, name, name)
{
_scRoot = scRoot;
_activeMonitorStatus = true;
}
~ITAUPS()
{
_connection.Disconnect();
}
public bool IsReceive = false;
public void QueryOids()
{
IsReceive = false;
//UPS二代
foreach (var oid in Oids)
{
if (oid.Key != null)
{
_lstHandler.AddLast(new ITAUPSGetHandler(this, oid.Key, "Get", oid.Value));
}
}
//if (SystemStatus == "Critical")
//{
// _lstHandler.AddLast(new ITAUPSGetBulkHandler(this, "AlarmTrap", "GetBulk", "1.3.6.1.4.1.13400.2.54.3.1.6"));
//}
}
public Dictionary<string, string> Oids = new Dictionary<string, string>()
{
{ "SystemStatus",".1.3.6.1.4.1.13400.2.54.2.1.1.0"},//在设备上测试了,返回信息感觉没啥用
{ "InputVoltage",".1.3.6.1.4.1.13400.2.54.2.2.1.0"},//输入电压输入电压为0说明使用UPS要除10
{ "BatteryVoltage",".1.3.6.1.4.1.13400.2.54.2.5.1.0"},//电池当前电压要除10
{ "BatteryRemainsTime",".1.3.6.1.4.1.13400.2.54.2.5.7.0"},//剩余时间,要除10
{ "upsOutputSource",".1.3.6.1.4.1.13400.2.54.2.1.2.0"},//当前输出源
{ "BatteryUnderResidue",".1.3.6.1.4.1.13400.2.54.2.5.10.0"}//电量剩余百分比,直接用数值
//除10的数据四舍五入
};
public void ResetDevice()
{
}
public void QueryError()
{
EV.PostInfoLog(Module, "Query error");
}
public bool Initialize()
{
//_connection的底层写死使用161端口号
portName = SC.GetStringValue($"PM.{Module}.{Name}.Address");
Address = portName;
int address = SC.GetValue<int>($"PM.{Module}.{Name}.DeviceAddress");
_enableLog = SC.GetValue<bool>($"PM.{Module}.{Name}.EnableLogMessage");
_connection = new ITAUPSConnection(portName);
_connection.EnableLog(_enableLog);
_thread = new PeriodicJob(500, OnTimer, $"{Module}.{Name} MonitorHandler", true);
DATA.Subscribe($"{Module}.{Name}.InputVoltage", () => InputVoltage / 10);
DATA.Subscribe($"{Module}.{Name}.BatteryVoltage", () => BatteryVoltage / 10);
DATA.Subscribe($"{Module}.{Name}.BatteryRemainsTime", () => BatteryRemainsTime / 10);
DATA.Subscribe($"{Module}.{Name}.BatteryUnderResidue", () => BatteryUnderResidue);
//DATA.Subscribe($"{Module}.{Name}.UtilityPowerFailure", () => _trigUtilityPowerFailure.CLK);
//DATA.Subscribe($"{Module}.{Name}.BatteryUnderVoltage", () => _trigBatteryUnderVoltage.CLK);
ConnectionManager.Instance.Subscribe($"{Name}", this);
return true;
}
public int _connectTimes { get; set; }
bool CanConnect()
{
IPAddress ip = IPAddress.Parse(portName);
Ping ping = new Ping();
try
{
PingReply reply = ping.Send(ip);
return (reply.Status == IPStatus.Success);
}
catch (PingException)
{
return false;
}
}
private bool OnTimer()
{
try
{
_connection.MonitorTimeout();
if (!_connection.IsConnected || _connection.IsCommunicationError)//测试发现这个条件永远不会满足
{
//lock (_locker)
//{
// _lstHandler.Clear();
//}
//if (!_connection.Connect())
//{
// _trigRetryConnect.CLK = !_connection.IsConnected;
// if (_trigRetryConnect.Q)
// {
// EV.PostAlarmLog(Module, $"Can not connect with {_connection.Address}, {Module}.{Name}");
// }
//}
//else
//{
// _trigRetryConnect.RST = true;
// EV.PostInfoLog(Module, $"Connected with {_connection.Address}, {Module}.{Name}");
//}
}
HandlerBase handler = null;
lock (_locker)
{
if (_lstHandler.Count == 0)
QueryOids();
if (_lstHandler.Count > 0 && !_connection.IsBusy)
{
handler = _lstHandler.First.Value;
_lstHandler.RemoveFirst();
if (handler != null)
{
_connection.Execute(handler);
}
}
}
if (!IsReceive) //单纯断联重连判断
{
System.Threading.Thread.Sleep(3000);//不加延时第一次启动时未连接,可能不报警
_trigRetryConnect.CLK = true;//断联
if (_trigRetryConnect.Q)
{
InputVoltage = 0;
BatteryUnderResidue = 0;
BatteryVoltage = 0;
BatteryRemainsTime = 0;
EV.PostAlarmLog(Module, $"Can not connect with {_connection.Address}, {Module}.{Name}");
}
_trigReconnection.RST = true;//复位重连
}
else
{
_trigReconnection.CLK = true;//重连
if (_trigReconnection.Q)
{
EV.PostInfoLog(Module, $"Connection with {_connection.Address}, {Module}.{Name}");
}
_trigRetryConnect.RST = true;//复位断联
}
}
catch (Exception ex)
{
LOG.Write(ex);
}
return true;
}
internal void NoteError()
{
}
public void Monitor()
{
}
public void Reset()
{
_connectTimes = 0;
_connection.SetCommunicationError(false, "");
_enableLog = SC.GetValue<bool>($"PM.{Module}.{Name}.EnableLogMessage");
_trigRetryConnect.RST = true;
_trigReconnection.RST = true;
}
public void PraseSystemStatus(string value)
{
if (value == "0")
{
SystemStatus = "Normal";
}
else if (value == "1")
{
SystemStatus = "Warning";
}
else if (value == "2")
{
if (UPSLowerBatteryAlarm)
{
SystemStatus = "LowerBattery";
}
else if (UPSPowerAlarm)
{
SystemStatus = "Power";
}
else
{
SystemStatus = "Critical";
}
}
}
public void ParseOutputSource(string value)
{
if (value == "0") //UPS No Output
{
UPSPowerAlarm = true;
}
else if (value == "1") // UPS On Main
{
UPSPowerAlarm = false;
}
else if (value == "2") //UPS On Battery
{
UPSPowerAlarm = true;
}
}
public void SetBatteryUnderResidue(int data)
{
BatteryUnderResidue = data;
//有数据时判断剩余电量百分比
if ( (30 >= BatteryUnderResidue) && (BatteryUnderResidue >= 20) || (10 >= BatteryUnderResidue) && (BatteryUnderResidue >= 1))
{
_trigPowerLow.CLK = true;
if (_trigPowerLow.Q)
EV.PostAlarmLog(Module, $"Attention {Module}.{Name} Is Power Low, Battery Under Residue {BatteryUnderResidue}%");
}
else
_trigPowerLow.RST = true;//不满足报警条件时自动复位,准备下次报警操作
}
public void UtilityPowerAlarm(bool alarm)
{
UPSPowerAlarm = alarm;
}
public void BatteryUnderVoltage(bool alarm)
{
UPSLowerBatteryAlarm = alarm;
}
public void Terminate()
{
_connection.Disconnect();
}
}
}