/// <summary> /// Initializes a new instance of the <see cref="TcpReadCommand"/> class. /// </summary> /// <param name="client"></param> /// <param name="logger"></param> public TcpReadCommand(ITcpModbusClient client, ILogger <TcpReadCommand> logger) : base("read", "Supporting Modbus TCP read operations.") { // Setup command options. AddOption(new Option <bool> (new string[] { "-?", "--help" }, "Show help and usage information")); AddOption(new Option <bool> (new string[] { "-c", "--coil" }, "Reads coil(s)")); AddOption(new Option <bool> (new string[] { "-d", "--discrete" }, "Reads discrete input(s)")); AddOption(new Option <bool> (new string[] { "-h", "--holding" }, "Reads holding register(s)")); AddOption(new Option <bool> (new string[] { "-i", "--input" }, "Reads input register(s)")); AddOption(new Option <bool> (new string[] { "-x", "--hex" }, "Displays the values in HEX")); AddOption(new Option <ushort>(new string[] { "-n", "--number" }, "The number of items to read").Name("Number").Default((ushort)1)); AddOption(new Option <ushort>(new string[] { "-o", "--offset" }, "The offset of the first item").Name("Offset").Default((ushort)0)); AddOption(new Option <string>(new string[] { "-t", "--type" }, "Reads the specified data type").Name("Type") .FromAmong("bits", "string", "byte", "short", "ushort", "int", "uint", "float", "double", "long", "ulong")); // Add custom validation. AddValidator(r => { var optionHelp = r.Children.Contains("?"); var optionC = r.Children.Contains("c"); var optionD = r.Children.Contains("d"); var optionH = r.Children.Contains("h"); var optionI = r.Children.Contains("i"); var optionX = r.Children.Contains("x"); var optionN = r.Children.Contains("n"); var optionO = r.Children.Contains("o"); var optionT = r.Children.Contains("t"); if ((!optionC && !optionD && !optionH && !optionI) || ((optionC && (optionD || optionH || optionI)) || (optionD && (optionC || optionH || optionI)) || (optionH && (optionD || optionC || optionI)) || (optionI && (optionD || optionH || optionC))) || optionHelp) { return("Specify a single read option (coils, discrete inputs, holding registers, input registers)."); } return(null); }); // Setup execution handler. Handler = CommandHandler.Create <IConsole, bool, TcpReadCommandOptions>((console, verbose, options) => { logger.LogInformation("Handler()"); // Run additional checks on options. options.CheckOptions(console); // Using TCP client options. client.TcpSlave.Address = options.Address; client.TcpSlave.Port = options.Port; client.TcpSlave.ID = options.SlaveID; client.TcpMaster.ReceiveTimeout = options.ReceiveTimeout; client.TcpMaster.SendTimeout = options.SendTimeout; if (verbose) { console.Out.WriteLine($"Modbus Commandline Application: {RootCommand.ExecutableName}"); console.Out.WriteLine(); console.Out.Write("TcpMasterData: "); console.Out.WriteLine(JsonSerializer.Serialize <TcpMasterData>(client.TcpMaster, _jsonoptions)); console.Out.Write("TcpSlaveData: "); console.Out.WriteLine(JsonSerializer.Serialize <TcpSlaveData>(client.TcpSlave, _jsonoptions)); console.Out.WriteLine(); } try { if (client.Connect()) { // Reading coils. if (options.Coil) { CommandHelper.ReadingCoils(console, client, options.SlaveID, options.Number, options.Offset); } // Reading discrete inputs. if (options.Discrete) { CommandHelper.ReadingDiscreteInputs(console, client, options.SlaveID, options.Number, options.Offset); } // Reading holding registers. if (options.Holding) { CommandHelper.ReadingHoldingRegisters(console, client, options.SlaveID, options.Number, options.Offset, options.Type, options.Hex); } // Reading input registers. if (options.Input) { CommandHelper.ReadingInputRegisters(console, client, options.SlaveID, options.Number, options.Offset, options.Type, options.Hex); } } else { console.Out.WriteLine($"Modbus TCP slave not found at {options.Address}:{options.Port}."); return(ExitCodes.NotSuccessfullyCompleted); } } catch (Exception ex) { console.Out.WriteLine($"Exception: {ex.Message}"); return(ExitCodes.UnhandledException); } finally { if (client.Connected) { client.Disconnect(); } } return(ExitCodes.SuccessfullyCompleted); }); }
/// <summary> /// Initializes a new instance of the <see cref="RtuWriteCommand"/> class. /// </summary> /// <param name="client"></param> /// <param name="logger"></param> public RtuWriteCommand(IRtuModbusClient client, ILogger <RtuReadCommand> logger) : base("write", "Supporting Modbus RTU write operations.") { // Setup command arguments and options. AddOption(new Option <bool> (new string[] { "-?", "--help" }, "Show help and usage information")); AddOption(new Option <string>(new string[] { "-c", "--coil" }, "Write coil(s).").Name("Json")); AddOption(new Option <string>(new string[] { "-h", "--holding" }, "Writes holding register(s).").Name("Json")); AddOption(new Option <bool> (new string[] { "-x", "--hex" }, "Writes the HEX values (string)")); AddOption(new Option <ushort>(new string[] { "-o", "--offset" }, "The offset of the first item.").Name("Offset").Default((ushort)0)); AddOption(new Option <string>(new string[] { "-t", "--type" }, "Reads the specified data type").Name("Type") .FromAmong("bits", "string", "byte", "short", "ushort", "int", "uint", "float", "double", "long", "ulong")); // Add custom validation. AddValidator(r => { var optionHelp = r.Children.Contains("?"); var optionC = r.Children.Contains("c"); var optionH = r.Children.Contains("h"); var optionX = r.Children.Contains("x"); var optionO = r.Children.Contains("o"); var optionT = r.Children.Contains("t"); if ((!optionC && !optionH) || (optionC && optionH) || optionHelp) { return("Specify a single write option (coils or holding registers)."); } return(null); }); // Setup execution handler. Handler = CommandHandler.Create <IConsole, bool, RtuWriteCommandOptions>((console, verbose, options) => { logger.LogInformation("Handler()"); // Run additional checks on options. options.CheckOptions(console); // Using RTU client options. client.RtuMaster.SerialPort = options.SerialPort; client.RtuMaster.Baudrate = options.Baudrate; client.RtuMaster.Parity = options.Parity; client.RtuMaster.DataBits = options.DataBits; client.RtuMaster.StopBits = options.StopBits; client.RtuMaster.ReadTimeout = options.ReadTimeout; client.RtuMaster.WriteTimeout = options.WriteTimeout; client.RtuSlave.ID = options.SlaveID; if (verbose) { console.Out.WriteLine($"Modbus Commandline Application: {RootCommand.ExecutableName}"); console.Out.WriteLine(); console.Out.Write("RtuMasterData: "); console.Out.WriteLine(JsonSerializer.Serialize <RtuMasterData>(client.RtuMaster, _jsonoptions)); console.Out.Write("RtuSlaveData: "); console.Out.WriteLine(JsonSerializer.Serialize <RtuSlaveData>(client.RtuSlave, _jsonoptions)); console.Out.WriteLine(); } try { if (client.Connect()) { // Writing coils. CommandHelper.WritingCoils(console, client, options.SlaveID, options.Offset, options.Coil); // Writing holding registers. CommandHelper.WritingHoldingRegisters(console, client, options.SlaveID, options.Offset, options.Holding, options.Type, options.Hex); } else { Console.WriteLine($"Modbus RTU slave not found at {options.SerialPort}."); return(ExitCodes.NotSuccessfullyCompleted); } } catch (JsonException jex) { console.Out.WriteLine(jex.Message); return(ExitCodes.NotSuccessfullyCompleted); } catch (Exception ex) { console.Out.WriteLine($"Exception: {ex.Message}"); return(ExitCodes.UnhandledException); } finally { if (client.Connected) { client.Disconnect(); } } return(ExitCodes.SuccessfullyCompleted); }); }