public RequestExtendedStruct(FunctionType functionCode, MEIType mei, DeviceIDCategory deviceIdCat, DeviceIDObject deviceIdObj) { FunctionCode = functionCode; MEI = mei; DeviceIdCat = deviceIdCat; DeviceIdObj = deviceIdObj; }
/// <summary> /// Reads device information. (Modbus function 43). /// </summary> /// <param name="deviceId">The id to address the device (slave).</param> /// <param name="categoryId">The category to read (basic, regular, extended, individual).</param> /// <param name="objectId">The first object id to read.</param> /// <returns>A map of device information and their content as raw bytes.</returns>> public async Task <Dictionary <byte, byte[]> > ReadDeviceInformationRaw(byte deviceId, DeviceIDCategory categoryId, DeviceIDObject objectId = DeviceIDObject.VendorName) { logger?.LogTrace($"ModbusClient.ReadDeviceInformation({deviceId}, {categoryId}, {objectId})"); if (isDisposed) { throw new ObjectDisposedException(GetType().FullName); } if (deviceId < Consts.MinDeviceIdRtu || Consts.MaxDeviceId < deviceId) { throw new ArgumentOutOfRangeException(nameof(deviceId)); } try { var request = new Request { DeviceId = deviceId, Function = FunctionCode.EncapsulatedInterface, MEIType = MEIType.ReadDeviceInformation, MEICategory = categoryId, MEIObject = objectId }; var response = await SendRequest(request); if (response.IsTimeout) { throw new IOException("Request timed out"); } if (response.IsError) { throw new ModbusException(response.ErrorMessage); } var dict = new Dictionary <byte, byte[]>(); for (int i = 0, idx = 0; i < response.ObjectCount && idx < response.Data.Length; i++) { byte objId = response.Data.GetByte(idx); idx++; byte len = response.Data.GetByte(idx); idx++; byte[] data = response.Data.GetBytes(idx, len); idx += len; dict.Add(objId, data); } if (response.MoreRequestsNeeded) { var transDict = await ReadDeviceInformationRaw(deviceId, categoryId, (DeviceIDObject)response.NextObjectId); foreach (var kvp in transDict) { dict.Add(kvp.Key, kvp.Value); } } return(dict); } catch (IOException ex) { logger?.LogWarning(ex, "Reading device information. Reconnecting."); ConnectingTask = Task.Run((Action)Reconnect); } return(null); }
/// <summary> /// Reads device information. (Modbus function 43). /// </summary> /// <param name="deviceId">The id to address the device (slave).</param> /// <param name="categoryId">The category to read (basic, regular, extended, individual).</param> /// <param name="objectId">The first object id to read.</param> /// <returns>A map of device information and their content as string.</returns> public async Task <Dictionary <DeviceIDObject, string> > ReadDeviceInformation(byte deviceId, DeviceIDCategory categoryId, DeviceIDObject objectId = DeviceIDObject.VendorName) { var raw = await ReadDeviceInformationRaw(deviceId, categoryId, objectId); if (raw == null) { return(null); } var dict = new Dictionary <DeviceIDObject, string>(); foreach (var kvp in raw) { dict.Add((DeviceIDObject)kvp.Key, Encoding.ASCII.GetString(kvp.Value)); } return(dict); }
/// <summary> /// Reads device information. (Modbus function 43). /// </summary> /// <param name="deviceId">The id to address the device (slave).</param> /// <param name="categoryId">The category to read (basic, regular, extended, individual).</param> /// <param name="objectId">The first object id to read.</param> /// <returns>A map of device information and their content as raw bytes.</returns> public async Task <Dictionary <byte, byte[]> > ReadDeviceInformationRaw(byte deviceId, DeviceIDCategory categoryId, DeviceIDObject objectId = DeviceIDObject.VendorName) { logger?.LogTrace($"ModbusClient.ReadDeviceInformation({deviceId}, {categoryId}, {objectId})"); if (deviceId < Consts.MinDeviceIdTcp || Consts.MaxDeviceId < deviceId) { throw new ArgumentOutOfRangeException(nameof(deviceId)); } try { var request = new Request { DeviceId = deviceId, Function = FunctionCode.EncapsulatedInterface, MEIType = MEIType.ReadDeviceInformation, MEICategory = categoryId, MEIObject = objectId }; var response = await SendRequest(request, mainCts.Token); if (response.IsTimeout) { throw new SocketException((int)SocketError.TimedOut); } if (response.IsError) { throw new ModbusException(response.ErrorMessage) { ErrorCode = response.ErrorCode }; } if (request.TransactionId != response.TransactionId) { throw new ModbusException(nameof(response.TransactionId) + " does not match"); } var dict = new Dictionary <byte, byte[]>(); for (int i = 0, idx = 0; i < response.ObjectCount && idx < response.Data.Length; i++) { byte objId = response.Data.GetByte(idx); idx++; byte len = response.Data.GetByte(idx); idx++; byte[] bytes = response.Data.GetBytes(idx, len); idx += len; dict.Add(objId, bytes); } if (response.MoreRequestsNeeded) { var transDict = await ReadDeviceInformationRaw(deviceId, categoryId, (DeviceIDObject)response.NextObjectId); foreach (var kvp in transDict) { dict.Add(kvp.Key, kvp.Value); } } return(dict); } catch (SocketException ex) { logger?.LogWarning(ex, "ModbusClient.ReadDeviceInformation failed. Reconnecting."); Task.Run(() => Reconnect(mainCts.Token)).Forget(); ConnectingTask = GetWaitTask(mainCts.Token); } catch (IOException ex) { logger?.LogWarning(ex, "ModbusClient.ReadDeviceInformation failed. Reconnecting."); Task.Run(() => Reconnect(mainCts.Token)).Forget(); ConnectingTask = GetWaitTask(mainCts.Token); } return(null); }