[성현모] CPXV2 Init
This commit is contained in:
@ -0,0 +1,314 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reactive.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SystemX.Net.Platform.Common.Event;
|
||||
using SystemX.Net.Platform.Common.Util;
|
||||
using static SystemX.PLC.Interface.PLCCommDefinition;
|
||||
|
||||
namespace SystemX.PLC.Interface.MxComponent
|
||||
{
|
||||
public class PLCDeviceMXC
|
||||
{
|
||||
public FunctionEventHandler EventAlwaysUpdate { get; set; }
|
||||
public FunctionEventHandler EventChangeUpdate { get; set; }
|
||||
|
||||
public int STATION_ID { set; get; } //PLC STATION
|
||||
|
||||
private int ScanningIntervalOperation = 100;
|
||||
private int ScanningIntervalDataTime = 500;
|
||||
|
||||
private bool MonitorExe = true;
|
||||
|
||||
private Stopwatch stReadTimeCheck;
|
||||
|
||||
private PLCMxComponent _conn; //MxComponent PLC Instance
|
||||
|
||||
Dictionary<string, PLCAddressTemplate> DicOperationAddresses = new Dictionary<string, PLCAddressTemplate>();
|
||||
Dictionary<string, PLCAddressTemplate> DicDataAddresses = new Dictionary<string, PLCAddressTemplate>();
|
||||
|
||||
Stopwatch xSwDiag = new Stopwatch();
|
||||
|
||||
private static object objLock = new object();
|
||||
|
||||
public PLCDeviceMXC()
|
||||
{
|
||||
stReadTimeCheck = new Stopwatch();
|
||||
stReadTimeCheck.Start();
|
||||
}
|
||||
|
||||
public bool DevClose()
|
||||
{
|
||||
if (_conn != null)
|
||||
{
|
||||
StopMonitor();
|
||||
|
||||
return _conn.Close();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool DevOpen()
|
||||
{
|
||||
try
|
||||
{
|
||||
_conn = new PLCMxComponent();
|
||||
|
||||
_conn.Initialize();
|
||||
|
||||
return _conn.Open(STATION_ID.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogMessage.MessageOutput.ConsoleWrite($"Error during PLC Open : {ex.Message}", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool AddOperationDevices(PLCAddressTemplate deviceReg)
|
||||
{
|
||||
DicOperationAddresses.Add(deviceReg.PLCAddress, deviceReg);
|
||||
|
||||
return true;
|
||||
}
|
||||
public bool AddDataDevices(PLCAddressTemplate deviceReg)
|
||||
{
|
||||
DicDataAddresses.Add(deviceReg.PLCAddress, deviceReg);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SingleScanStartAsync()
|
||||
{
|
||||
lock (objLock)
|
||||
{
|
||||
ScanDataArea();
|
||||
|
||||
ScanOperationArea(true);
|
||||
}
|
||||
}
|
||||
public void NowDataAreaScan()
|
||||
{
|
||||
lock (objLock)
|
||||
{
|
||||
ScanDataArea();
|
||||
}
|
||||
}
|
||||
public void StartMonitor()
|
||||
{
|
||||
MonitorExe = true;
|
||||
|
||||
Task<int> monitor = new Task<int>(() => ExecuteMonitor().Result);
|
||||
|
||||
monitor.Start();
|
||||
}
|
||||
|
||||
public void StopMonitor()
|
||||
{
|
||||
MonitorExe = false;
|
||||
}
|
||||
|
||||
private async Task<int> ExecuteMonitor()
|
||||
{
|
||||
//int nCountTime = 0;
|
||||
|
||||
stReadTimeCheck.Restart();
|
||||
|
||||
while (MonitorExe)
|
||||
{
|
||||
lock (objLock)
|
||||
{
|
||||
ScanOperationArea();
|
||||
|
||||
/*
|
||||
if (stReadTimeCheck.ElapsedMilliseconds >= ScanningIntervalDataTime)
|
||||
{
|
||||
ScanDataArea();
|
||||
|
||||
stReadTimeCheck.Restart();
|
||||
}
|
||||
*/
|
||||
|
||||
//
|
||||
|
||||
/*
|
||||
if (nCountTime % ScanningIntervalDataTime == 0)
|
||||
{
|
||||
nCountTime = 1;
|
||||
|
||||
ScanDataArea();
|
||||
}
|
||||
|
||||
nCountTime++;
|
||||
*/
|
||||
}
|
||||
|
||||
await Task.Delay(ScanningIntervalOperation);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ScanDataArea()
|
||||
{
|
||||
foreach (PLCAddressTemplate addrTemplate in DicDataAddresses.Values)
|
||||
UpdateDevice(addrTemplate, true);
|
||||
}
|
||||
|
||||
void ScanOperationArea(bool bSingleScan = false)
|
||||
{
|
||||
foreach (PLCAddressTemplate addrTemplate in DicOperationAddresses.Values)
|
||||
{
|
||||
string strFormerValue = addrTemplate.Value;
|
||||
|
||||
UpdateDevice(addrTemplate, true);
|
||||
|
||||
EventAlwaysUpdate.DoReceive(this, addrTemplate);
|
||||
|
||||
if (addrTemplate.Value != strFormerValue)
|
||||
EventChangeUpdate.DoReceive(this, addrTemplate);
|
||||
|
||||
if (bSingleScan)
|
||||
EventChangeUpdate.DoReceive(this, addrTemplate);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetModuleName()
|
||||
{
|
||||
return Assembly.GetExecutingAssembly().ManifestModule.Name.Replace(".dll", string.Empty);
|
||||
}
|
||||
|
||||
Int16[] ReadPLCData(PLCAddressTemplate template)
|
||||
{
|
||||
if (_conn == null)
|
||||
return null;
|
||||
|
||||
int nSize = Convert.ToInt32(template.Length);
|
||||
|
||||
Int16[] readData = new Int16[nSize];
|
||||
|
||||
_conn.BlockReadData(template.PLCAddress, nSize, ref readData);
|
||||
|
||||
return readData;
|
||||
}
|
||||
|
||||
bool WritePLCData(PLCAddressTemplate template, Int16[] arnWriteData)
|
||||
{
|
||||
if (_conn == null)
|
||||
return false;
|
||||
|
||||
int nSize = Convert.ToInt32(template.Length);
|
||||
|
||||
bool ret = _conn.BlockWriteData(template.PLCAddress, nSize, arnWriteData);
|
||||
|
||||
if (ret == false)
|
||||
{
|
||||
_conn.BlockWriteData(template.PLCAddress, nSize, arnWriteData);
|
||||
|
||||
Thread.Sleep(30);
|
||||
}
|
||||
|
||||
Thread.Sleep(30);
|
||||
|
||||
//bool ret = PLC_COMM.WriteData(addr, nSize, arnWriteData);
|
||||
return ret;
|
||||
}
|
||||
|
||||
List<int> GetReadValues(PLCAddressTemplate tmplt)
|
||||
{
|
||||
int nLength = Convert.ToInt32(tmplt.Length);
|
||||
|
||||
List<int> vnValues = (from value in ReadPLCData(tmplt) let value32 = Convert.ToInt32(value) select value32).ToList();
|
||||
|
||||
return vnValues;
|
||||
}
|
||||
|
||||
List<short> GetWriteValues(PLCAddressTemplate tmplt, string strValue)
|
||||
{
|
||||
List<short> vnValues = new List<short>();
|
||||
|
||||
int nLength = Convert.ToInt32(tmplt.Length);
|
||||
|
||||
eDataType eType = (eDataType)Enum.Parse(typeof(eDataType), tmplt.DataType);
|
||||
|
||||
if (eType == eDataType.ASCII)
|
||||
vnValues = (from value in CommonUtil.HexStringToBytes(strValue) select Convert.ToInt16(value)).ToList();
|
||||
else if (eType == eDataType.DECIMAL)
|
||||
{
|
||||
int nInputValue = string.IsNullOrWhiteSpace(strValue) ? 0 : Convert.ToInt16(strValue);
|
||||
vnValues.Add(Convert.ToInt16(nInputValue));
|
||||
}
|
||||
|
||||
return vnValues;
|
||||
}
|
||||
|
||||
void UpdateValue(PLCAddressTemplate tmplt, bool bRefineWrongChar, bool bAsciiReverseBit = false)
|
||||
{
|
||||
List<int> vValues = GetReadValues(tmplt);
|
||||
|
||||
eDataType eType = (eDataType)Enum.Parse(typeof(eDataType), tmplt.DataType);
|
||||
|
||||
string strData = string.Empty;
|
||||
|
||||
if (eType == eDataType.ASCII)
|
||||
strData = CommonUtil.GetStringFromASCII(vValues.ToArray(), bAsciiReverseBit);
|
||||
else if (eType == eDataType.BIT)
|
||||
strData = vValues[0].ToString();
|
||||
else if (eType == eDataType.DECIMAL)
|
||||
strData = vValues[0].ToString();
|
||||
|
||||
string strResult = bRefineWrongChar ? RefineInvalidChars(strData) : strData;
|
||||
|
||||
tmplt.SetStringValue(strResult);
|
||||
}
|
||||
|
||||
string RefineInvalidChars(string strSource)
|
||||
{
|
||||
string strReturn = strSource.Trim(InvalidChars);
|
||||
|
||||
strReturn = new string((from cCode in strSource.ToCharArray() where (48 <= Convert.ToInt32(cCode) && Convert.ToInt32(cCode) <= 95) select cCode).ToArray());
|
||||
|
||||
return strReturn;
|
||||
}
|
||||
|
||||
public string GetDeviceValue(PLCAddressTemplate tmplt)
|
||||
{
|
||||
List<PLCAddressTemplate> Oper = DicOperationAddresses.Values.Where(x => x.DataName == tmplt.DataName).ToList();
|
||||
List<PLCAddressTemplate> Data = DicDataAddresses.Values.Where(x => x.DataName == tmplt.DataName).ToList();
|
||||
|
||||
if (Oper.Count > 0)
|
||||
return Oper.First().Value;
|
||||
else if (Data.Count > 0)
|
||||
return Data.First().Value;
|
||||
else
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public PLCAddressTemplate UpdateDevice(PLCAddressTemplate tmplt, bool bRefineWrongChar, bool bAsciiReverse = false)
|
||||
{
|
||||
if (tmplt == null)
|
||||
{
|
||||
LogMessage.MessageOutput.ConsoleWrite($"Cannot Find a Corresponding Data.");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
UpdateValue(tmplt, bRefineWrongChar, bAsciiReverse);
|
||||
|
||||
return tmplt;
|
||||
}
|
||||
|
||||
public bool WriteDevice(PLCAddressTemplate tmplt, string strValue)
|
||||
{
|
||||
List<short> vValues = GetWriteValues(tmplt, strValue);
|
||||
|
||||
return WritePLCData(tmplt, vValues.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user