/// <summary> /// MC プロトコルの終了コードの詳細を取得します。 /// </summary> /// <param name="endCode">MC プロトコルの終了コードを指定します。</param> /// <returns>詳細情報を返します。</returns> public static string GetDescription(this McEndCode endCode) { var fieldInfo = endCode.GetType().GetField(endCode.ToString()); var attribute = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false).FirstOrDefault() as DescriptionAttribute; return(attribute != null ? attribute.Description : null); }
/// <summary> /// ワード単位の一括読出しをおこないます。 /// </summary> /// <typeparam name="T">受信処理結果の型を表します。</typeparam> /// <param name="type">デバイス種別を指定します。</param> /// <param name="topAddress">読み出すデバイスの先頭アドレスを指定します。</param> /// <param name="dataNumbers">読み出すデバイスのワード数を指定します。</param> /// <param name="func">受信処理を指定します。</param> /// <returns>終了コードと受信処理結果のペアを返します。</returns> public KeyValuePair <McEndCode, T> ReadDevice <T>(McWordDeviceType type, int topAddress, int dataNumbers, Func <IEnumerable <byte>, int, T> func) { if (this._isDisposed) { throw new ObjectDisposedException("Dispose されたものは使用できません。", null as Exception); } if (!this.IsConnected) { throw new Exception("接続していません。"); } // 要求データ作成 var command = new byte[] { 0x01, 0x04 }; var subCommand = new byte[] { 0x00, 0x00 }; var address = BitConverter.GetBytes(topAddress).Take(3).ToArray(); var deviceCode = new byte[] { (byte)type }; var dataNumbersBytes = BitConverter.GetBytes((ushort)dataNumbers); var request = new byte[command.Length + subCommand.Length + address.Length + deviceCode.Length + dataNumbersBytes.Length]; Array.Copy(command, 0, request, 0, command.Length); Array.Copy(subCommand, 0, request, command.Length, subCommand.Length); Array.Copy(address, 0, request, command.Length + subCommand.Length, address.Length); Array.Copy(deviceCode, 0, request, command.Length + subCommand.Length + address.Length, deviceCode.Length); Array.Copy(dataNumbersBytes, 0, request, command.Length + subCommand.Length + address.Length + deviceCode.Length, dataNumbersBytes.Length); // 要求伝文生成 var bytes = this._3eFrame.CreateRequestMessage(request); // 伝文送信 this._stream.Write(bytes, 0, bytes.Length); // 応答受信 var n = this._stream.Read(this._buffer, 0, this._buffer.Length); // サブヘッダ取得 //ushort subHeader = 0; //if (n >= 2) subHeader = BitConverter.ToUInt16(this._buffer, 0); // アクセス経路取得 //if (n >= 7) ... // 応答データ長 ushort length = 0; if (n >= 9) { length = BitConverter.ToUInt16(this._buffer, 7); } // 終了コード McEndCode endCode = McEndCode.UnKnown; if (n >= 11) { endCode = (McEndCode)BitConverter.ToUInt16(this._buffer, 9); } // データ部取得 T data = default(T); if (endCode == McEndCode.Success) { var dataLength = length - 2; // 終了コード 2 バイト分を除いた値がデータ部の長さ if ((dataLength > 0) && (n == 11 + dataLength)) { data = func(this._buffer, dataNumbers); } } return(new KeyValuePair <McEndCode, T>(endCode, data)); }
/// <summary> /// ワード単位のランダム読出しをおこないます。 /// </summary> /// <param name="bitDevices">読み出すビットデバイス群を指定します。</param> /// <param name="wordDevices">読み出すワードデバイス群を指定します。</param> /// <param name="doubleWordDevices">読み出すダブルワードデバイス群を指定します。</param> /// <returns>終了コードと受信処理結果のペアを返します。データ数が 1 回の通信に収まらない場合は未定義のエラーコード <c>McEndCode.Unknown</c> を返します。</returns> public KeyValuePair <McEndCode, short[]> ReadDevice(IEnumerable <IMcBitDevice> bitDevices, IEnumerable <IMcWordDevice> wordDevices, IEnumerable <IMcDoubleWordDevice> doubleWordDevices) { if (this._isDisposed) { throw new ObjectDisposedException("Dispose されたものは使用できません。", null as Exception); } if (!this.IsConnected) { throw new Exception("接続していません。"); } // データ数が 1 回の通信に収まらない場合は未定義のエラーコードを返す var bitDeviceLength = bitDevices.Count(); var wordDeviceLength = wordDevices.Count(); var doubleWordDeviceLength = doubleWordDevices.Count(); var dataNumbers = bitDeviceLength + wordDeviceLength + 2 * doubleWordDeviceLength; if (dataNumbers > McConnection.MaxRandomReadLength) { return(new KeyValuePair <McEndCode, short[]>(McEndCode.UnKnown, null)); } // 要求データ作成 var command = new byte[] { 0x03, 0x04 }; var subCommand = new byte[] { 0x00, 0x00 }; var wordLength = new byte[] { (byte)(bitDeviceLength + wordDeviceLength), (byte)doubleWordDeviceLength }; var deviceBytes = bitDevices.SelectMany(x => x.Bytes).Concat(wordDevices.SelectMany(x => x.Bytes)).Concat(doubleWordDevices.SelectMany(x => x.Bytes)).ToArray(); var request = new byte[command.Length + subCommand.Length + wordLength.Length + deviceBytes.Length]; Array.Copy(command, 0, request, 0, command.Length); Array.Copy(subCommand, 0, request, command.Length, subCommand.Length); Array.Copy(wordLength, 0, request, command.Length + subCommand.Length, wordLength.Length); Array.Copy(deviceBytes, 0, request, command.Length + subCommand.Length + wordLength.Length, deviceBytes.Length); // 要求伝文生成 var bytes = this._3eFrame.CreateRequestMessage(request); // 伝文送信 this._stream.Write(bytes, 0, bytes.Length); // 応答受信 var n = this._stream.Read(this._buffer, 0, this._buffer.Length); // サブヘッダ取得 //ushort subHeader = 0; //if (n >= 2) subHeader = BitConverter.ToUInt16(this._buffer, 0); // アクセス経路取得 //if (n >= 7) ... // 応答データ長 ushort length = 0; if (n >= 9) { length = BitConverter.ToUInt16(this._buffer, 7); } // 終了コード McEndCode endCode = McEndCode.UnKnown; if (n >= 11) { endCode = (McEndCode)BitConverter.ToUInt16(this._buffer, 9); } // データ部取得 short[] data = null; if (endCode == McEndCode.Success) { var dataLength = length - 2; // 終了コード 2 バイト分を除いた値がデータ部の長さ if ((dataLength > 0) && (n == 11 + dataLength)) { data = WordDeviceReader(this._buffer, dataNumbers); } } return(new KeyValuePair <McEndCode, short[]>(endCode, data)); }