Files
DT_BR_GUI/LFP_Manager/Threads/CsSnmpThread.cs
2025-12-17 12:40:51 +09:00

527 lines
20 KiB
C#

using LFP_Manager.DataStructure;
using LFP_Manager.Function;
using SnmpSharpNet;
using System;
using System.Net;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using LFP_Manager.Utils;
using System.Windows.Forms;
using static DevExpress.Xpo.Helpers.AssociatedCollectionCriteriaHelper;
namespace LFP_Manager.Threads
{
public delegate void SetResult(string result, bool error);
public delegate void DataUpdate(object sender, ref DeviceSystemData rData);
class CsSnmpThread
{
#region VARIABLES
private DeviceSystemData SystemData;
private CommConfig Config;
private Thread snmpThread = null;
private bool snmpThreadHold = true;
private string targetIP = "";
private bool snmpDataRecv = false;
private string snmpResult = "";
private bool AutoSnmpTx = true;
private int type = 0;
private int OidIndex = 0;
private int OidMax = 0;
private int OidIndexBase = 0;
private int CommTimeOut = 0;
private string[] OidList;
private int SetSnmpMode = 0;
private int SetSnmpMode1 = 0;
private UInt32 SetSnmpValue = 0;
private string SetSnmpStringData;
public event DataUpdate OnUpdate = null;
public event SetResult OnSetResult = null;
#endregion
#region CONSTRUCTORS
public CsSnmpThread()
{
snmpThread = new Thread(snmpThreadFuncA);
snmpThread.Start();
}
public CsSnmpThread(CommConfig aConfig, ref DeviceSystemData aSystemData)
{
Config = aConfig;
type = Config.SnmpModelIndex;
OidIndex = 0;
OidList = CsSnmpConstData.SnmpOidInfo;
OidMax = OidList.Length;
SystemData = aSystemData;
snmpThread = new Thread(snmpThreadFuncA);
snmpThread.Start();
}
#endregion
#region PUBLIC FUNCTION
public void disposeThread()
{
snmpThreadHold = true;
snmpThread.Abort();
}
public void Start(string IP, bool autoTx)
{
targetIP = IP;
snmpThreadHold = false;
AutoSnmpTx = autoTx;
}
public void Stop()
{
snmpThreadHold = true;
}
public bool GetStatus()
{
return snmpThreadHold;
}
public string GetResult()
{
string result = "";
if (snmpDataRecv)
{
result = snmpResult;
snmpDataRecv = false;
}
return result;
}
public void SetAutoTx(bool autoTx)
{
AutoSnmpTx = autoTx;
}
#endregion
#region COMM. THREAD
public string GetSnmpOidInfo(int index)
{
return OidList[index];
}
bool SetCmdbySnmp(UdpTarget sTarget, int mode, UInt32 value, string svalue)
{
bool resultError = false;
Pdu SetPdu = new Pdu(PduType.Set);
// Set a value to unsigned integer
SetPdu.VbList.Clear();
switch (mode)
{
case 1: // Reset Command
SetPdu.VbList.Add(new Oid(".1.3.6.1.4.1.33.13.1.0"), new Integer32(Convert.ToInt32(value)));
break;
case 2: // Module Quantity Set
SetPdu.VbList.Add(new Oid(".1.3.6.1.4.1.33.2.4.0"), new Integer32(Convert.ToInt32(value)));
break;
case 3: // Alarm Output Mode
SetPdu.VbList.Add(new Oid(".1.3.6.1.4.1.33.2.5.0"), new Integer32(Convert.ToInt32(value)));
break;
case 4: // Manufacture Date
SetPdu.VbList.Add(new Oid(".1.3.6.1.4.1.33.2.6.0"), new Integer32(Convert.ToInt32(value)));
break;
case 5: // BMS Serial Number
SetPdu.VbList.Add(new Oid(".1.3.6.1.4.1.33.2.7.0"), new OctetString(svalue));
break;
}
// Set Agent security parameters
AgentParameters aparam = new AgentParameters(SnmpVersion.Ver1, new OctetString("public"));
// Make SNMP request
try
{
// Send request and wait for response
SnmpV1Packet result = sTarget.Request(SetPdu, aparam) as SnmpV1Packet;
// If result is null then agent didn't reply or we couldn't parse the reply.
if (result != null)
{
// ErrorStatus other then 0 is an error returned by
// the Agent - see SnmpConstants for error definitions
if (result.Pdu.ErrorStatus != 0)
{
// agent reported an error with the request
snmpResult = String.Format("Error in SNMP reply. Error {0} index {1}",
result.Pdu.ErrorStatus,
result.Pdu.ErrorIndex);
if (OnSetResult != null)
{
OnSetResult(snmpResult, true);
}
}
else
{
// Everything is ok. Agent will return the new value for the OID we changed
string resultString;
if (result.Pdu.VbList[0].Type == AsnType.OCTETSTRING)
resultString = result.Pdu.VbList[0].Value.ToString();
else
resultString = result.Pdu.VbList[0].Value.ToString();
snmpResult = String.Format("SNMP Received data. result {0}",
resultString);
OnSetResult?.Invoke(snmpResult, false);
}
}
else
{
if (snmpDataRecv == false)
{
snmpResult = DateTime.Now.ToString("[yyyy-MM-dd hh:mm:ss] ") + String.Format("No response received from SNMP agent.");
snmpDataRecv = true;
OnSetResult?.Invoke(snmpResult, true);
}
}
}
catch (Exception ex)
{
if (snmpDataRecv == false)
{
snmpResult = "[" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") + "] " + String.Format("Exception : {0}", ex.Message);
snmpDataRecv = true;
OnSetResult?.Invoke(snmpResult, true);
}
resultError = true;
}
return resultError;
}
public void SetDataBySnmp(int mode, UInt32 value)
{
SetSnmpMode = mode;
SetSnmpValue = value;
}
public void SetDataBySnmp(int mode, string value)
{
SetSnmpMode1 = mode;
SetSnmpStringData = value;
}
private void snmpThreadFuncA()
{
while (true)
{
if (snmpThreadHold == false)
{
// SNMP community name
OctetString community = new OctetString("admin");
// Define agent parameters class
AgentParameters param = new AgentParameters(community);
// Set SNMP version to 1 (or 2)
param.Version = SnmpVersion.Ver1;
// Construct the agent address object
// IpAddress class is easy to use here because
// it will try to resolve constructor parameter if it doesn't
// parse to an IP address
String dstAddr = targetIP;
IpAddress agent = new IpAddress(dstAddr);
// Construct target
UdpTarget target = new UdpTarget((IPAddress)agent, 161, 1000, 1);
// Pdu class used for all requests
Pdu pdu = new Pdu(PduType.Get);
if (SetSnmpMode != 0)
{
SetCmdbySnmp(target, SetSnmpMode, SetSnmpValue, SetSnmpStringData);
SetSnmpMode = 0;
}
else if (SetSnmpMode1 != 0)
{
SetCmdbySnmp(target, SetSnmpMode1, SetSnmpValue, SetSnmpStringData);
SetSnmpMode1 = 0;
}
else
{
// SNMP GET
while (AutoSnmpTx)
{
snmpResult = "";
if ((SetSnmpMode != 0) || (SetSnmpMode1 != 0))
{
break;
}
pdu.VbList.Clear();
pdu.VbList.Add(GetSnmpOidInfo(OidIndex));
// Make SNMP request
try
{
//SnmpV1Packet result = (SnmpV1Packet)target.Request(pdu, param);
target.Timeout = 100;
// agent reported an error with the request
snmpResult = csLog.trx_msg_print(string.Format("SEND {0}: OID [{1}]"
, target.Address.ToString()
, pdu.VbList[0].Oid.ToString()
)
, 0
)
;
OnSetResult?.Invoke(snmpResult, true);
SnmpV1Packet result = (SnmpV1Packet)target.Request(pdu, param);
// If result is null then agent didn't reply or we couldn't parse the reply.
if (result != null)
{
// ErrorStatus other then 0 is an error returned by
// the Agent - see SnmpConstants for error definitions
if (result.Pdu.ErrorStatus != 0)
{
// agent reported an error with the request
snmpResult = csLog.trx_msg_print(string.Format("Error in SNMP reply. Error {0} index {1} - {2}"
, result.Pdu.ErrorStatus
, result.Pdu.ErrorIndex
, result.Pdu.VbList[0].Oid.ToString()
)
, 1
)
;
OnSetResult?.Invoke(snmpResult, true);
}
else
{
snmpResult = csLog.trx_msg_print(string.Format("RECV {0}: OID [{1}]: [{2}]"
, target.Address.ToString()
, result.Pdu.VbList[0].Oid.ToString()
, result.Pdu.VbList[0].Value.ToString()
)
, 1
)
;
OnSetResult?.Invoke(snmpResult, true);
String resultTxt = "";
// Reply variables are returned in the same order as they were added
// to the VbList
//resultTxt = String.Format("[{0}] ({1}): {2}",
// result.Pdu.VbList[0].Oid.ToString(),
// SnmpConstants.GetTypeName(result.Pdu.VbList[0].Value.Type),
// result.Pdu.VbList[0].Value.ToString());
resultTxt = String.Format(".{0}", result.Pdu.VbList[0].Oid.ToString());
uint[] resultInt = (uint[])result.Pdu.VbList[0].Oid;
int len = resultInt.Length;
if ((resultInt[0] == 1)
&& (resultInt[1] == 3)
&& (resultInt[2] == 6)
&& (resultInt[3] == 1)
&& (resultInt[4] == 2)
&& (resultInt[5] == 1)
&& (resultInt[6] == 15)
)
{
//double resultDouble = 0.0;
if (result.Pdu.VbList[0].Value.Type == AsnType.OCTETSTRING)
{
try
{
//resultDouble = Convert.ToDouble(result.Pdu.VbList[0].Value.ToString());
csMakeDataFunction.SetSnmpData((int)resultInt[7], result.Pdu.VbList[0].Value.ToString(), ref SystemData);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
else if (result.Pdu.VbList[0].Type == AsnType.OCTETSTRING)
{
MessageBox.Show(result.Pdu.VbList[0].Value.ToString());
}
CalcAvgTemperatureModule(ref SystemData, (uint)SystemData.tempQty);
CheckShelfCommFail(ref SystemData);
OnUpdate?.Invoke(this, ref SystemData);
}
CommTimeOut = 0;
SystemData.CommFail = false;
}
Thread.Sleep(50);
}
else
{
if (snmpDataRecv == false)
{
snmpResult = DateTime.Now.ToString("[yyyy-MM-dd hh:mm:ss] ") + String.Format("No response received from SNMP agent.");
snmpDataRecv = true;
}
CommTimeOut++;
if (CommTimeOut >= 20)
{
SystemData.CommFail = true;
InitModuleData();
CommTimeOut = 20;
}
}
OidIndex++;
OidIndex %= OidMax;
Thread.Sleep(1);
}
catch (Exception ex)
{
snmpResult = csLog.trx_msg_print(string.Format("Exception in SNMP reply. Error {0} - {1}"
, pdu.VbList[0].Oid.ToString()
, ex.Message
)
, 1
)
;
OnSetResult?.Invoke(snmpResult, true);
CommTimeOut++;
if (CommTimeOut >= 10)
{
SystemData.CommFail = true;
InitModuleData();
CommTimeOut = 10;
}
break;
}
}
CheckShelfCommFail(ref SystemData);
OnUpdate?.Invoke(this, ref SystemData);
}
pdu.Clone();
target.Close();
Thread.Sleep(500);
}
}
}
private void InitModuleData()
{
SystemData.ValueData.voltageOfPack = 0;
SystemData.ValueData.current = 0;
SystemData.ValueData.averageCurrent = 0;
SystemData.ValueData.rSOC = 0;
SystemData.ValueData.stateOfHealth = 0;
for (int i = 0; i < SystemData.ValueData.CellVoltage.Length; i++)
{
SystemData.ValueData.CellVoltage[i] = 0;
}
for (int i = 0; i < SystemData.ValueData.CellTemperature.Length; i++)
{
SystemData.ValueData.CellTemperature[i] = 0;
}
SystemData.AvgData.avgCellVoltage = 0;
SystemData.AvgData.diffCellVoltage = 0;
SystemData.AvgData.maxCellVoltage = 0;
SystemData.AvgData.minCellVoltage = 0;
SystemData.AvgData.maxCellNum = 0;
SystemData.AvgData.minCellNum = 0;
SystemData.AvgData.avgTemp = 0;
SystemData.AvgData.diffTemp = 0;
SystemData.AvgData.maxTemp = 0;
SystemData.AvgData.minTemp = 0;
SystemData.AvgData.maxTempNum = 0;
SystemData.AvgData.minTempNum = 0;
}
private void CheckShelfCommFail(ref DeviceSystemData aSystemData)
{
if (aSystemData.StatusData.batteryStatus == 0x0003)
{ aSystemData.ShelfCommFail = true; }
else
{ aSystemData.ShelfCommFail = false; }
}
#endregion
static void CalcAvgTemperatureModule(ref DeviceSystemData aSystemData, UInt32 tSize)
{
short i, j;
int sum;
TMinMax min, max;
min = new TMinMax();
max = new TMinMax();
sum = 0;
max.value = 0;
max.num = 0;
min.value = 0;
min.num = 0;
j = 0;
for (i = 0; i < tSize; i++)
{
if (j == 0)
{
max.value = aSystemData.ValueData.CellTemperature[i];
max.num = i;
min.value = aSystemData.ValueData.CellTemperature[i];
min.num = i;
}
if (max.value < aSystemData.ValueData.CellTemperature[i])
{
max.value = aSystemData.ValueData.CellTemperature[i];
max.num = i;
}
if (min.value > aSystemData.ValueData.CellTemperature[i])
{
min.value = aSystemData.ValueData.CellTemperature[i];
min.num = i;
}
sum += aSystemData.ValueData.CellTemperature[i];
j++;
}
if (j == 0)
{ aSystemData.AvgData.avgTemp = 0; }
else
{ aSystemData.AvgData.avgTemp = (short)(sum / j); }
aSystemData.AvgData.maxTemp = max.value;
aSystemData.AvgData.maxTempNum = max.num;
aSystemData.AvgData.minTemp = min.value;
aSystemData.AvgData.minTempNum = min.num;
}
}
}