using MagFlux6200_metrology_reg_list; using System.Collections.Generic; using System.Numerics; using System; using XYLEM.Communication; using System.IO.Ports; using XYLEM.Base.Files; using System.Threading.Tasks; using XYLEM.Base; namespace XYLEM.Device { public abstract class ModbusDeviceCom { protected ProgramLogCSVFileClass _logger = null; UInt16 _device_id = 1; ModbusCom _md_com = null; #if (!DEBUG) public Boolean DoComDebugPrint = false; #else //public Boolean DoComDebugPrint = true; public Boolean DoComDebugPrint = false; #if (DoComDebugPrint) #warning DoTxValuePrint is true!!!!!!!!!!!!!!!! #endif const int ch_lng_dv = -15; const int ch_lng_Version = -3; const int ch_lng_MD_adr = -7; const int dig_value = 10; #endif public ModbusDeviceCom() { } public Boolean SetLogLocation(string path, string filename) { try { // If already created a _logger then if (_logger != null) { // TODO: nothing to do right now throw new Exception("Logger path can only be set one time"); } _logger = new ProgramLogCSVFileClass(path, filename); return true; // Okay } catch (Exception ex) { Console.WriteLine($"Fail to setup program log path!\nPath:{path}\nMessage:{ex.Message}"); } return false; // failed } public void OpenLogFile() { // If already created a _logger then if (_logger != null) { _logger.OpenProgramLogFile(); } } public string GetComCounters() { if (_md_com == null) { return "T=? E=?"; } return $"T={_md_com.MsgCount} E={_md_com.MsgErrorCount}"; } public Boolean IsConnected() { if (_md_com == null) { return false; } return _md_com.IsConnected(); } public Boolean CloseConnection() { try { StopBackgroundChecking(); if (_md_com != null) { /*There is nothing to close right now*/ } return true; // is okay } catch (Exception ex) { _logger.AddFuncLog(true, this.ToString(), "CloseConnection", "Fail to close connection", ex); } return false; // failed } public virtual Boolean Connect(string comport, int baudRate, Parity parity) { try { {// Normal if (IsConnected()) { CloseConnection(); } _md_com = new ModbusCom(comport, baudRate, parity); return _md_com.IsConnected(); // return result } } catch (Exception ex) { _logger.AddFuncLog(true, this.ToString(), "Connect", "Fail to open connection", ex); } return false; // failed } #region Background service System.Timers.Timer _BackgroundCheckingTimer = null; protected void StartBackgroundChecking() { StopBackgroundChecking(); // Make sure that a already running one is stopped _BackgroundCheckingTimer = new System.Timers.Timer(1000); _BackgroundCheckingTimer.Elapsed += (sender, e) => HandleBackgroundChecking(); _BackgroundCheckingTimer.Start(); } protected void StopBackgroundChecking() { if (_BackgroundCheckingTimer != null) { _BackgroundCheckingTimer.Stop(); _BackgroundCheckingTimer.Close(); _BackgroundCheckingTimer = null; } } /// /// Handle checking DUT and background reading device values /// /// private void HandleBackgroundChecking() { // Don't continue background service before the first has been serviced if (_BackgroundCheckingTimer != null) { _BackgroundCheckingTimer.Stop(); } try { RunBackgroundReadServiceFunction(); } catch (Exception ex) { #if (DEBUG) var message = $"Fail background service handling"; Console.WriteLine(message); AppConst.Logger.AddFuncLog(true, this.ToString(), "HandleBackgroundChecking()", message, ex); #endif // #if (DEBUG) } // Don't continue background service before the first has been serviced if (_BackgroundCheckingTimer != null) { _BackgroundCheckingTimer.Start(); } } /// /// Need to be overwritten with a function for polling periodically read information from device for checking health etc. /// protected abstract void RunBackgroundReadServiceFunction(); #endregion // Background service #region ---------------- Generic modbus communications --------------------- protected UInt16? read_U16(Device_value dv) { var ret = _md_com.Read(_device_id, dv, new UInt16()); if (ret.IsOkay) { var value = ret.Data; #if (DEBUG) if (DoComDebugPrint) { Console.WriteLine($"Read={dv,ch_lng_dv}: Reg_Ver={dv.Version,ch_lng_Version} Adr={dv.MD_adr,ch_lng_MD_adr} value={value,dig_value}"); } #endif // #if (DEBUG) return value; } return null; // Error in reading } protected UInt32? read_U32(Device_value dv) { var ret = _md_com.Read(_device_id, dv, new UInt32()); if (ret.IsOkay) { var value = ret.Data; #if (DEBUG) if (DoComDebugPrint) { Console.WriteLine($"Read={dv,ch_lng_dv}: Reg_Ver={dv.Version,ch_lng_Version} Adr={dv.MD_adr,ch_lng_MD_adr} value={value,dig_value}"); } #endif // #if (DEBUG) return value; } return null; // Error in reading } protected Single? read_F32(Device_value dv) { var ret = _md_com.Read(_device_id, dv, new Single()); if (ret.IsOkay) { var value = ret.Data; #if (DEBUG) if (DoComDebugPrint) { Console.WriteLine($"Read={dv,ch_lng_dv}: Reg_Ver={dv.Version,ch_lng_Version} Adr={dv.MD_adr,ch_lng_MD_adr} value={value,dig_value}"); } #endif // #if (DEBUG) return value; } return null; // Error in reading } protected BigInteger? read_U128(Device_value dv) { var ret = _md_com.Read(_device_id, dv, new BigInteger()); if (ret.IsOkay) { var value = ret.Data; #if (DEBUG) if (DoComDebugPrint) { Console.WriteLine($"Read={dv,ch_lng_dv}: Reg_Ver={dv.Version,ch_lng_Version} Adr={dv.MD_adr,ch_lng_MD_adr} value={value,dig_value}"); } #endif // #if (DEBUG) return value; } return null; // Error in reading } protected List read(List dvList) { var ret = _md_com.Read(_device_id, dvList); if (ret.Count > 0) { #if (DEBUG) foreach (var data in ret) { if (DoComDebugPrint) { var dv = data.Info; Console.WriteLine($"Read={dv,ch_lng_dv}: Reg_Ver={dv.Version,ch_lng_Version} Adr={dv.MD_adr,ch_lng_MD_adr} value={data.Data,dig_value}"); } } #endif // #if (DEBUG) return ret; } return null; // Error in reading } protected bool write_U16(Device_value dv, UInt16 value) { var isOkay = _md_com.Write(_device_id, dv, value); if (!isOkay) { #if (DEBUG) if (DoComDebugPrint) { Console.WriteLine($"Failed Write={dv,ch_lng_dv}: Reg_Ver={dv.Version,ch_lng_Version} Adr={dv.MD_adr,ch_lng_MD_adr} value={value,dig_value}"); } #endif // #if (DEBUG) } return isOkay; // Error in reading } protected bool write_U32(Device_value dv, UInt32 value) { var isOkay = _md_com.Write(_device_id, dv, value); if (!isOkay) { #if (DEBUG) if (DoComDebugPrint) { Console.WriteLine($"Failed Write={dv,ch_lng_dv}: Reg_Ver={dv.Version,ch_lng_Version} Adr={dv.MD_adr,ch_lng_MD_adr} value={value,dig_value}"); } #endif // #if (DEBUG) } return isOkay; // Error in reading } /// /// Write multiple values in a optimized number of telegrams /// /// /// protected List write(List reqList) { var ret = _md_com.Write(_device_id, reqList); if ((ret!=null) && (ret.Count > 0)) { #if (DEBUG) foreach (var data in ret) { if (DoComDebugPrint) { var dv = data.Info; Console.WriteLine($"Write={dv,ch_lng_dv}: Reg_Ver={dv.Version,ch_lng_Version} Adr={dv.MD_adr,ch_lng_MD_adr} value={data.Data,dig_value} {data.IsOkay}"); } } #endif // #if (DEBUG) return ret; } return null; // Error in reading } #endregion // #region ---------------- Generic modbus communications --------------------- } }