2023-03-03 15:42:13 +08:00
|
|
|
|
using Aitex.Core.RT.DataCenter;
|
|
|
|
|
using Aitex.Core.RT.Device;
|
2023-03-11 09:15:28 +08:00
|
|
|
|
using Aitex.Core.RT.Device.Devices;
|
2023-03-03 15:42:13 +08:00
|
|
|
|
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;
|
2023-03-11 09:15:28 +08:00
|
|
|
|
using System.Net.NetworkInformation;
|
|
|
|
|
using System.Net;
|
2023-03-03 15:42:13 +08:00
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.UPS
|
|
|
|
|
{
|
2023-03-11 09:15:28 +08:00
|
|
|
|
public class ITAUPS : BaseDevice, IConnection, IDevice
|
2023-03-03 15:42:13 +08:00
|
|
|
|
{
|
|
|
|
|
private ITAUPSConnection _connection;
|
|
|
|
|
private bool _activeMonitorStatus;
|
|
|
|
|
private int _errorCode;
|
2023-03-11 09:15:28 +08:00
|
|
|
|
|
|
|
|
|
private R_TRIG _trigRetryConnect = new R_TRIG();//断开上升沿
|
|
|
|
|
private R_TRIG _trigReconnection = new R_TRIG();//重连上升沿
|
|
|
|
|
private R_TRIG _trigPowerLow = new R_TRIG();//缺电上升沿
|
2023-03-03 15:42:13 +08:00
|
|
|
|
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;
|
2023-03-11 09:15:28 +08:00
|
|
|
|
private string portName;
|
2023-03-03 15:42:13 +08:00
|
|
|
|
|
|
|
|
|
private string _systemStatus;
|
|
|
|
|
private float _inputVoltage;
|
|
|
|
|
private float _batteryVoltage;
|
|
|
|
|
private float _batteryRemainsTime;
|
2023-03-11 09:15:28 +08:00
|
|
|
|
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; }
|
2023-03-03 15:42:13 +08:00
|
|
|
|
public bool UPSPowerAlarm { get; set; }
|
|
|
|
|
public bool UPSLowerBatteryAlarm { get; set; }
|
|
|
|
|
|
2023-03-11 09:15:28 +08:00
|
|
|
|
public int ErrorNum { get; set; } = 0;
|
|
|
|
|
|
|
|
|
|
|
2023-03-03 15:42:13 +08:00
|
|
|
|
public string Address
|
|
|
|
|
{
|
|
|
|
|
get; set;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool IsConnected
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return _connection != null && _connection.IsConnected;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public bool Connect()
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Disconnect()
|
|
|
|
|
{
|
2023-03-11 09:15:28 +08:00
|
|
|
|
_connection.Disconnect();
|
2023-03-03 15:42:13 +08:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-11 09:15:28 +08:00
|
|
|
|
public ITAUPS(string module, string name, string scRoot, DOAccessor BatteryLowVoltage, DOAccessor UpsEnable) : base(module, name, name, name)
|
2023-03-03 15:42:13 +08:00
|
|
|
|
{
|
|
|
|
|
_scRoot = scRoot;
|
|
|
|
|
_activeMonitorStatus = true;
|
2023-03-11 09:15:28 +08:00
|
|
|
|
|
2023-03-03 15:42:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~ITAUPS()
|
|
|
|
|
{
|
|
|
|
|
_connection.Disconnect();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-11 09:15:28 +08:00
|
|
|
|
public bool IsReceive = false;
|
2023-03-03 15:42:13 +08:00
|
|
|
|
public void QueryOids()
|
|
|
|
|
{
|
2023-03-11 09:15:28 +08:00
|
|
|
|
IsReceive = false;
|
2023-03-03 15:42:13 +08:00
|
|
|
|
//UPS二代
|
2023-03-11 09:15:28 +08:00
|
|
|
|
foreach (var oid in Oids)
|
2023-03-03 15:42:13 +08:00
|
|
|
|
{
|
|
|
|
|
if (oid.Key != null)
|
|
|
|
|
{
|
|
|
|
|
_lstHandler.AddLast(new ITAUPSGetHandler(this, oid.Key, "Get", oid.Value));
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-03-11 09:15:28 +08:00
|
|
|
|
//if (SystemStatus == "Critical")
|
|
|
|
|
//{
|
|
|
|
|
// _lstHandler.AddLast(new ITAUPSGetBulkHandler(this, "AlarmTrap", "GetBulk", "1.3.6.1.4.1.13400.2.54.3.1.6"));
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
2023-03-03 15:42:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Dictionary<string, string> Oids = new Dictionary<string, string>()
|
|
|
|
|
{
|
2023-03-11 09:15:28 +08:00
|
|
|
|
{ "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的数据四舍五入
|
2023-03-03 15:42:13 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
public void ResetDevice()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void QueryError()
|
|
|
|
|
{
|
|
|
|
|
EV.PostInfoLog(Module, "Query error");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Initialize()
|
|
|
|
|
{
|
2023-03-11 09:15:28 +08:00
|
|
|
|
//_connection的底层写死使用161端口号
|
|
|
|
|
portName = SC.GetStringValue($"PM.{Module}.{Name}.Address");
|
2023-03-03 15:42:13 +08:00
|
|
|
|
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);
|
|
|
|
|
|
2023-03-11 09:15:28 +08:00
|
|
|
|
_thread = new PeriodicJob(500, OnTimer, $"{Module}.{Name} MonitorHandler", true);
|
2023-03-03 15:42:13 +08:00
|
|
|
|
|
2023-03-11 09:15:28 +08:00
|
|
|
|
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);
|
2023-03-03 15:42:13 +08:00
|
|
|
|
|
2023-03-11 09:15:28 +08:00
|
|
|
|
//DATA.Subscribe($"{Module}.{Name}.UtilityPowerFailure", () => _trigUtilityPowerFailure.CLK);
|
|
|
|
|
//DATA.Subscribe($"{Module}.{Name}.BatteryUnderVoltage", () => _trigBatteryUnderVoltage.CLK);
|
2023-03-03 15:42:13 +08:00
|
|
|
|
|
|
|
|
|
ConnectionManager.Instance.Subscribe($"{Name}", this);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
public int _connectTimes { get; set; }
|
2023-03-11 09:15:28 +08:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-03-03 15:42:13 +08:00
|
|
|
|
private bool OnTimer()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
_connection.MonitorTimeout();
|
|
|
|
|
|
2023-03-11 09:15:28 +08:00
|
|
|
|
if (!_connection.IsConnected || _connection.IsCommunicationError)//测试发现这个条件永远不会满足
|
2023-03-03 15:42:13 +08:00
|
|
|
|
{
|
2023-03-11 09:15:28 +08:00
|
|
|
|
//lock (_locker)
|
2023-03-03 15:42:13 +08:00
|
|
|
|
//{
|
2023-03-11 09:15:28 +08:00
|
|
|
|
// _lstHandler.Clear();
|
|
|
|
|
//}
|
|
|
|
|
//if (!_connection.Connect())
|
|
|
|
|
//{
|
|
|
|
|
// _trigRetryConnect.CLK = !_connection.IsConnected;
|
|
|
|
|
// if (_trigRetryConnect.Q)
|
2023-03-03 15:42:13 +08:00
|
|
|
|
// {
|
|
|
|
|
// EV.PostAlarmLog(Module, $"Can not connect with {_connection.Address}, {Module}.{Name}");
|
|
|
|
|
// }
|
|
|
|
|
//}
|
2023-03-11 09:15:28 +08:00
|
|
|
|
//else
|
|
|
|
|
//{
|
|
|
|
|
// _trigRetryConnect.RST = true;
|
|
|
|
|
// EV.PostInfoLog(Module, $"Connected with {_connection.Address}, {Module}.{Name}");
|
|
|
|
|
//}
|
2023-03-03 15:42:13 +08:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-11 09:15:28 +08:00
|
|
|
|
|
2023-03-03 15:42:13 +08:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-03-11 09:15:28 +08:00
|
|
|
|
|
|
|
|
|
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;//复位断联
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-03 15:42:13 +08:00
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
LOG.Write(ex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal void NoteError()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Monitor()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Reset()
|
|
|
|
|
{
|
|
|
|
|
_connectTimes = 0;
|
2023-03-11 09:15:28 +08:00
|
|
|
|
_connection.SetCommunicationError(false, "");
|
|
|
|
|
|
2023-03-03 15:42:13 +08:00
|
|
|
|
_enableLog = SC.GetValue<bool>($"PM.{Module}.{Name}.EnableLogMessage");
|
|
|
|
|
_trigRetryConnect.RST = true;
|
2023-03-11 09:15:28 +08:00
|
|
|
|
_trigReconnection.RST = true;
|
2023-03-03 15:42:13 +08:00
|
|
|
|
}
|
|
|
|
|
public void PraseSystemStatus(string value)
|
|
|
|
|
{
|
2023-03-11 09:15:28 +08:00
|
|
|
|
|
2023-03-03 15:42:13 +08:00
|
|
|
|
if (value == "0")
|
|
|
|
|
{
|
|
|
|
|
SystemStatus = "Normal";
|
2023-03-11 09:15:28 +08:00
|
|
|
|
|
2023-03-03 15:42:13 +08:00
|
|
|
|
}
|
|
|
|
|
else if (value == "1")
|
|
|
|
|
{
|
|
|
|
|
SystemStatus = "Warning";
|
2023-03-11 09:15:28 +08:00
|
|
|
|
|
2023-03-03 15:42:13 +08:00
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-11 09:15:28 +08:00
|
|
|
|
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;//不满足报警条件时自动复位,准备下次报警操作
|
|
|
|
|
}
|
2023-03-03 15:42:13 +08:00
|
|
|
|
public void UtilityPowerAlarm(bool alarm)
|
|
|
|
|
{
|
|
|
|
|
UPSPowerAlarm = alarm;
|
2023-03-11 09:15:28 +08:00
|
|
|
|
|
2023-03-03 15:42:13 +08:00
|
|
|
|
}
|
|
|
|
|
public void BatteryUnderVoltage(bool alarm)
|
|
|
|
|
{
|
|
|
|
|
UPSLowerBatteryAlarm = alarm;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void Terminate()
|
|
|
|
|
{
|
|
|
|
|
_connection.Disconnect();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|