Files
CPXV2/SystemX.Net.CP.Platform/SystemX.PLC/Interface/McProtocol/PLCCommMcPMgr.cs
2024-06-26 10:30:00 +09:00

498 lines
17 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
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.McProtocol
{
public class PLCCommMcPMgr : PLCCommManager
{
private int TimeOut;
public Dictionary<ePLCRWType, PLCModMxCMgr> PLCManagers { get; set; } = new Dictionary<ePLCRWType, PLCModMxCMgr>();
public PLCCommMcPMgr(string strPLCConnInfoXmlPath)
: base(strPLCConnInfoXmlPath)
{
AddrMgr = new PLCAddressManager(strPLCConnInfoXmlPath);
EventChangeUpdate = new FunctionEventHandler();
TimeOut = 0;
foreach (PLCConnectionInfo coninfo in AddrMgr.ConnInfoDictionary.Values)
{
if (TimeOut < int.Parse(coninfo.Timeout))
TimeOut = int.Parse(coninfo.Timeout);
PLCManagers.Add((ePLCRWType)Enum.Parse(typeof(ePLCRWType), coninfo.RWType), new PLCModMxCMgr(coninfo));
}
}
public override bool OpenPLCConnection()
{
Task<bool> openconn = new Task<bool>(() => TryOpenPLCConnection());
openconn.Start();
bool bResult = openconn.Result;
if (bResult)
{
//Task plcoperation = openconn.ContinueWith(x => StartPLCOperation());
Task<bool> plcoperation = new Task<bool>(() => StartPLCOperation());
plcoperation.Start();
bResult = plcoperation.Result;
}
return bResult;
/*
if (plcoperation.Wait(TimeOut))
return true;
else
return false;
*/
}
public bool TryOpenPLCConnection()
{
try
{
foreach (PLCModMxCMgr conmgr in PLCManagers.Values)
{
if (!conmgr.OpenDevice())
return false;
Stopwatch stTimeOut = new Stopwatch();
stTimeOut.Start();
while (true)
{
if (conmgr.IsOpened == true)
break;
if (stTimeOut.ElapsedMilliseconds >= TimeOut)
{
LogMessage.MessageOutput.ConsoleWrite("PLC Connection Waiting TimeOut.", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL);
return false;
}
Thread.Sleep(50);
}
conmgr.EventPLC += ReceivePLCEvent;
SetAddress(conmgr, AddrMgr.OperationDictionary);
SetAddress(conmgr, AddrMgr.DataDictionary);
}
LogMessage.MessageOutput.ConsoleWrite("PLC Connection Waiting for Success.", ConsoleColor.Blue, LogMessage.LogMessageLevel.NONE);
return true;
}
catch (Exception ex)
{
LogMessage.MessageOutput.ConsoleWrite($"PLC Connection Open Error.\n - Error Message: {ex.Message}", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL);
return false;
}
}
public override bool StartPLCOperation()
{
try
{
Thread.Sleep(300);
PLCManagers[ePLCRWType.Read].SingleScanStartAsync(); // Do not use await
UpdateAll();
OperationStarted = true;
LogMessage.MessageOutput.ConsoleWrite("PLC Operation Started.", ConsoleColor.Blue, LogMessage.LogMessageLevel.NONE);
return true;
}
catch (Exception ex)
{
LogMessage.MessageOutput.ConsoleWrite($"PLC Connection Open Error.\n - Error Message: {ex.Message}", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL);
return false;
}
}
public override void NowScanDataArea()
{
}
public override bool ClosePLCConnection()
{
try
{
foreach (PLCModMxCMgr conmgr in PLCManagers.Values)
conmgr.CloseDevice();
OperationStarted = false;
return true;
}
catch (Exception ex)
{
LogMessage.MessageOutput.ConsoleWrite($"PLC Connection Close Error.\n - Error Message: {ex.Message}", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL);
return false;
}
}
public override void ReceivePLCEvent(string address, int value)
{
PLCAddressTemplate tmpltSearch = SearchMySubscription(address);
if (tmpltSearch == null)
return;
UpdateDevice(tmpltSearch, address, value);
EventChangeUpdate.DoReceive(this, address);
}
public PLCAddressTemplate SearchMySubscription(string strAddress)
{
PLCAddressTemplate tmpltOp = AddrMgr.FindPLCAddressElementByAssociatedKeyAddress(strAddress, AddrMgr.OperationDictionary);
PLCAddressTemplate tmpltData = AddrMgr.FindPLCAddressElementByAssociatedKeyAddress(strAddress, AddrMgr.DataDictionary);
if (tmpltOp != null)
return tmpltOp;
else
return tmpltData;
}
void SetAddress(PLCModMxCMgr module, Dictionary<string, PLCAddressTemplate> addressInfo)
{
foreach (PLCAddressTemplate addrinfo in addressInfo.Values)
{
int nLength = Convert.ToInt32(addrinfo.Length);
int nStartAddr = Convert.ToInt32(addrinfo.Address);
for (int i = 0; i < nLength; i++)
{
int nAddr = nStartAddr + i;
module.AddDevices(addrinfo.Area + nAddr.ToString());
}
}
}
public PLCAddressTemplate UpdateDevice(PLCAddressTemplate tmplt, string strDevice, int nValue)
{
if (tmplt == null)
{
LogMessage.MessageOutput.ConsoleWrite($"Cannot Find a Corresponding Data. Device: {strDevice}");
return null;
}
tmplt.UpdateValue(strDevice, nValue);
return tmplt;
}
public PLCAddressTemplate UpdateDevice(string strDevice)
{
PLCAddressTemplate tmplt = AddrMgr.FindPLCAddressElement(strDevice);
if (tmplt == null)
{
LogMessage.MessageOutput.ConsoleWrite($"Cannot Find a Corresponding Data. Device: {strDevice}");
return null;
}
UpdateValue(tmplt);
return tmplt;
}
void UpdateValue(PLCAddressTemplate tmplt)
{
List<int> vValues = GetReadValues(tmplt);
eDataType eType = (eDataType)Enum.Parse(typeof(eDataType), tmplt.DataType);
string strData = string.Empty;
tmplt.SetAssociatedValues(vValues);
}
public override string ReadDevice(string strDevice, bool bRefineWrongChar = true)
{
PLCAddressTemplate tmplt = UpdateDevice(strDevice);
return (tmplt != null) ? tmplt.Value : string.Empty;
}
public override string ReadDevice(PLCAddressTemplate tmplt)
{
try
{
tmplt = UpdateDevice(tmplt.AddressKey);
return (tmplt != null) ? tmplt.Value : string.Empty;
}
catch (Exception ex)
{
LogMessage.MessageOutput.ConsoleWrite($"PLC Manager is failed to Read Device. The Address: {tmplt.AddressKey} has not been read by unidentified errors. ", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL);
LogMessage.MessageOutput.ConsoleWrite($" - Error Message: {ex.Message}", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL);
return string.Empty;
}
}
public override void UpdateAll(bool bRefineWrongChar = false)
{
UpdateArea(AddrMgr.OperationDictionary.Keys.ToList());
UpdateArea(AddrMgr.DataDictionary.Keys.ToList());
}
public virtual void SelectUpdate(PLCAddressTemplate tmplt, bool bRefineWrongChar)
{
}
void UpdateArea(List<string> strKeys)
{
foreach (string strKey in strKeys)
UpdateDevice(strKey);
}
public override bool WriteDevice(PLCAddressTemplate tmplt, string strValue, bool bVerification = false)
{
try
{
tmplt.SetStringValue(strValue);
WriteDevice(tmplt);
if (bVerification)
{
string strReadValue = ReadDevice(tmplt.PLCAddress);
if (strReadValue == strValue)
{
LogMessage.MessageOutput.ConsoleWrite($"The Address: {tmplt.PLCAddress} has not been written #Intent:{strValue} - #Actual:{tmplt.Value} by unidentified errors. ", ConsoleColor.Red, LogMessage.LogMessageLevel.NONE);
return false;
}
}
return true;
}
catch (Exception ex)
{
LogMessage.MessageOutput.ConsoleWrite($"PLC Manager is failed to Write Device. The Address: {tmplt.AddressKey} has not been written by unidentified errors. ", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL);
LogMessage.MessageOutput.ConsoleWrite($" - Error Message: {ex.Message}", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL);
return false;
}
}
public void WriteDevice(string strDevice)
{
int nCount = 0;
if (!OperationStarted)
{
while (true)
{
if (OperationStarted || nCount > 100)
break;
nCount++;
Thread.Sleep(100);
}
}
PLCAddressTemplate tmplt = AddrMgr.FindPLCAddressElement(strDevice);
WriteDevice(tmplt);
}
public bool WriteDevice(PLCAddressTemplate tmplt)
{
try
{
int nCount = 0;
if (!OperationStarted)
{
while (true)
{
if (OperationStarted || nCount > 100)
break;
nCount++;
Thread.Sleep(100);
}
}
int nLength = Convert.ToInt32(tmplt.Length);
if (nLength > 1)
WriteBlockDevice(tmplt, nLength, tmplt.RawValue);
else
WriteDeviceSequence(tmplt, nLength, tmplt.RawValue);
//UpdateValue(tmplt, false);
return true;
}
catch (Exception ex)
{
LogMessage.MessageOutput.ConsoleWrite($"PLC Manager is failed to Write Device. The Address: {tmplt.AddressKey} has not been written by unidentified errors. ", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL);
LogMessage.MessageOutput.ConsoleWrite($" - Error Message: {ex.Message}", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL);
return false;
}
}
bool WriteBlockDevice(PLCAddressTemplate tmplt, int nLength, List<int> vnValues)
{
try
{
string strAddr = tmplt.Area + (Convert.ToInt32(tmplt.Address)).ToString();
bool result = PLCManagers[ePLCRWType.Write].WriteBlockDevice(strAddr, vnValues.Count, vnValues.ToArray());
return result;
/*
if (result)
{
int[] anResult = PLCManagers[ePLCRWType.Read].ReadBlockDevice(strAddr, nLength);
for(int nIdx = 0; nIdx < vnValues.Count; nIdx++)
if (anResult[nIdx] != vnValues[nIdx])
{
LogMessage.MessageOutput.ConsoleWrite($"During: WriteBlockDevice, The Address: {strAddr} + {nIdx} has not been written #Intent:{vnValues[nIdx]} - #Actual:{anResult[nIdx]} by unidentified errors. ", ConsoleColor.Red, LogMessage.LogMessageLevel.NONE);
return false;
}
}
*/
}
catch (Exception ex)
{
LogMessage.MessageOutput.ConsoleWrite($"During: WriteBlockDevice, PLC Manager is failed to Write Device. The Address: {tmplt.AddressKey} has not been written by unidentified errors. ", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL);
LogMessage.MessageOutput.ConsoleWrite($" - Error Message: {ex.Message}", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL);
return false;
}
}
bool WriteDeviceSequence(PLCAddressTemplate tmplt, int nLength, List<int> vnValues)
{
try
{
for (int i = 0; i < nLength; i++)
{
//LogMessage.MessageOutput.ConsoleWrite($"The Address: {tmplt.AddressKey}. ", ConsoleColor.Red, LogMessage.LogMessageLevel.NONE);
string strAddr = tmplt.Area + (Convert.ToInt32(tmplt.Address) + i).ToString();
bool result = PLCManagers[ePLCRWType.Write].WriteDevice(strAddr, vnValues[i]);
return result;
/*
if (i >= vnValues.Count)
PLCManagers[ePLCRWType.Write].WriteDevice(strAddr, 0);
else
{
bool result = PLCManagers[ePLCRWType.Write].WriteDevice(strAddr, vnValues[i]);
return result;
if (result)
{
int nResult = PLCManagers[ePLCRWType.Read].ReadDevice(strAddr);
if (nResult != vnValues[i])
{
LogMessage.MessageOutput.ConsoleWrite($"During: WriteDeviceSequence, The Address: {strAddr} has not been written #Intent:{vnValues[i]} - #Actual:{nResult} by unidentified errors. ", ConsoleColor.Red, LogMessage.LogMessageLevel.NONE);
return false;
}
}
}*/
}
}
catch (Exception ex)
{
LogMessage.MessageOutput.ConsoleWrite($"During: WriteDeviceSequence, PLC Manager is failed to Write Device. The Address: {tmplt.AddressKey} has not been written by unidentified errors. ", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL);
LogMessage.MessageOutput.ConsoleWrite($" - Error Message: {ex.Message}", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL);
return false;
}
return true;
}
List<int> GetWriteValues(PLCAddressTemplate tmplt)
{
List<int> vnValues = new List<int>();
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(tmplt.Value) select Convert.ToInt32(value)).ToList();
else if (eType == eDataType.DECIMAL)
{
int nInputValue = string.IsNullOrWhiteSpace(tmplt.Value) ? 0 : Convert.ToInt32(tmplt.Value);
vnValues.Add(nInputValue);
}
return vnValues;
}
List<int> GetReadValues(PLCAddressTemplate tmplt)
{
List<int> vnValues = new List<int>();
int nLength = Convert.ToInt32(tmplt.Length);
/*
for (int i = 0; i < nLength; i++)
{
int nAddress = Convert.ToInt32(tmplt.Address) + i;
int nValue = PLCManagers[ePLCRWType.Read].ReadDevice(tmplt.Area + nAddress.ToString());
vnValues.Add(nValue);
}
*/
if (nLength > 1)
{
int[] anResult = PLCManagers[ePLCRWType.Read].ReadBlockDevice(tmplt.PLCAddress, nLength);
if (anResult != null)
vnValues = anResult.ToList();
}
else
{
for (int i = 0; i < nLength; i++)
{
int nAddress = Convert.ToInt32(tmplt.Address) + i;
int nValue = PLCManagers[ePLCRWType.Read].ReadDevice(tmplt.Area + nAddress.ToString());
vnValues.Add(nValue);
}
}
return vnValues;
}
}
}