356 lines
11 KiB
C#
356 lines
11 KiB
C#
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();
|
||
}
|
||
|
||
}
|
||
}
|
||
|