protected FunctionServiceResult ProcessReadRegisters(Sample[] samples, PacketType? packetType) { //Get the raw bytes var messageBytes = samples .Select(s => s.Value) .ToArray(); //We'll assume that this is a response byte numberOfBytes = messageBytes[2]; //Get the number of registers var numberOfRegisters = numberOfBytes / 2; //Get the registers themselves var registers = GetRegisters(messageBytes, numberOfRegisters, 3); //Create the visual factory Func<Visual> visualFactory = () => { var viewModel = new RegistersViewModel(registers); return new RegistersView() { DataContext = viewModel }; }; var summary = $"{numberOfRegisters} registers."; return new FunctionServiceResult(summary, visualFactory, packetType); }
public static FunctionServiceResult Process(Sample[] samples) { try { IFunctionService service; if (samples.Length < 5) { return new FunctionServiceResult("Packet not long enough."); } byte rawFunctionCode = samples[1].Value; FunctionCode functionCode = (FunctionCode)(rawFunctionCode & 0x7F); if ((rawFunctionCode & 0x80) > 0) { var exceptionDescription = SlaveExceptionDescriptionFactory.GetExceptionDescription(samples[2].Value); return new FunctionServiceResult(error: exceptionDescription); } if (_functionServices.TryGetValue(functionCode, out service)) { return service.Process(samples); } return new FunctionServiceResult(error: "Unsupported function code."); } catch (Exception ex) { return new FunctionServiceResult(ex.Message); } }
public override FunctionServiceResult Process(Sample[] samples) { if (samples.Length == NumberOfRegistersMessageLength) { return ProcessNumberOfRegisters(samples, PacketType.Request); } return ProcessReadRegisters(samples, PacketType.Response); }
protected FunctionServiceResult ProcessNumberOfRegisters(Sample[] samples, PacketType? packetType) { if (samples.Length != NumberOfRegistersMessageLength) throw new ArgumentException($"The message must be 8 bytes long. It was {samples.Length}."); //Get the raw bytes var messageBytes = samples .Select(s => s.Value) .ToArray(); ushort address = EndianBitConverter.Big.ToUInt16(messageBytes, 2); ushort number = EndianBitConverter.Big.ToUInt16(messageBytes, 4); var summary = $"Read {number} registers starting at {address}"; return new FunctionServiceResult(summary, packetType: packetType); }
private FunctionServiceResult ProcessWriteRegisters(Sample[] samples) { // http://www.simplymodbus.ca/FC16.htm //Get the raw bytes var messageBytes = samples .Select(s => s.Value) .ToArray(); var dataAddress = EndianBitConverter.Big.ToUInt16(messageBytes, 2); var numberOfRegisters = EndianBitConverter.Big.ToUInt16(messageBytes, 4); var bytesToFollow = messageBytes[6]; if (bytesToFollow != numberOfRegisters*2) { return new FunctionServiceResult( $"The bytes to follow {bytesToFollow} does not match the number of registers {numberOfRegisters}."); } var registers = GetRegisters(messageBytes, numberOfRegisters, 7); Func<Visual> visualFactory = () => { var viewModel = new RegistersViewModel(registers.ToArray(), dataAddress); return new RegistersView() { DataContext = viewModel }; }; var summary = $"Write {numberOfRegisters} registers starting at register {dataAddress}"; return new FunctionServiceResult(summary, visualFactory, PacketType.Request); }
public abstract FunctionServiceResult Process(Sample[] samples);