public async void TimeoutIsResetAfterRequest() { // Arrange var endpoint = EndpointSource.GetNext(); var server = new ModbusTcpServer(); server.Start(endpoint); var client = new ModbusTcpClient(); client.Connect(endpoint); var delay = TimeSpan.FromSeconds(1); await Task.Run(async() => { var data = Enumerable.Range(0, 20).Select(i => (float)i).ToArray(); // Act await Task.Delay(delay); var lastRequest1 = server.RequestHandlerSet.First().LastRequest.Elapsed; client.WriteMultipleRegisters(0, 0, data); var lastRequest2 = server.RequestHandlerSet.First().LastRequest.Elapsed; client.Disconnect(); // Assert Assert.True(lastRequest1 >= delay); Assert.True(lastRequest2 < delay); }); server.Stop(); }
public async void ServerHandlesRequestFire() { // Arrange var endpoint = EndpointSource.GetNext(); using var server = new ModbusTcpServer(); server.Start(endpoint); // Act var client = new ModbusTcpClient(); client.Connect(endpoint); await Task.Run(() => { var data = Enumerable.Range(0, 20).Select(i => (float)i).ToArray(); var sw = Stopwatch.StartNew(); var iterations = 10000; for (int i = 0; i < iterations; i++) { client.WriteMultipleRegisters(0, 0, data); } var timePerRequest = sw.Elapsed.TotalMilliseconds / iterations; _logger.WriteLine($"Time per request: {timePerRequest * 1000:F0} us. Frequency: {1/timePerRequest * 1000:F0} requests per second."); client.Disconnect(); }); // Assert }
public async void ServerWorksWithExternalTcpClient() { // Arrange var endpoint = EndpointSource.GetNext(); var listener = new TcpListener(endpoint); using var server = new ModbusTcpServer(); var client = new ModbusTcpClient(); var expected = new double[] { 0.1, 0.2, 0.3, 0.4, 0.5 }; double[] actual = null; // Act listener.Start(); var clientTask = Task.Run(() => { client.Connect(endpoint); actual = client .ReadWriteMultipleRegisters <double, double>(0, 0, 5, 0, expected) .ToArray(); client.Disconnect(); }); var serverTask = Task.Run(() => { var tcpClient = listener.AcceptTcpClient(); server.Start(tcpClient); }); await clientTask; // Assert Assert.True(actual.SequenceEqual(expected)); }
static async Task Main(string[] args) { /* prepare dependency injection */ var services = new ServiceCollection(); ConfigureServices(services); /* create types */ var provider = services.BuildServiceProvider(); var loggerFactory = provider.GetRequiredService <ILoggerFactory>(); var serverLogger = loggerFactory.CreateLogger("Server"); var clientLogger = loggerFactory.CreateLogger("Client"); /* create Modbus TCP server and client */ var server = new ModbusTcpServer(serverLogger); var client = new ModbusTcpClient(); /* run Modbus TCP server (option 1) */ var cts = new CancellationTokenSource(); var task_server = Task.Run(async() => { server.Start(); while (!cts.IsCancellationRequested) { // lock is required to synchronize buffer access between this application and one or more Modbus clients lock (server.Lock) { DoServerWork(server); } // update server buffer content once per second await Task.Delay(TimeSpan.FromSeconds(1)); } server.Dispose(); }, cts.Token); /* run Modbus TCP client */ var task_client = Task.Run(() => { client.Connect(); try { DoClientWork(client, clientLogger); } catch (Exception ex) { clientLogger.LogError(ex.Message); } client.Disconnect(); Console.WriteLine("Tests finished. Press any key to continue."); Console.ReadKey(true); }); // wait for client task to finish await task_client; // stop server cts.Cancel(); await task_server; server.Stop(); serverLogger.LogInformation("Server stopped."); }
static async Task Main(string[] args) { /* create logger */ var loggerFactory = LoggerFactory.Create(loggingBuilder => { loggingBuilder.SetMinimumLevel(LogLevel.Debug); loggingBuilder.AddConsole(); }); var serverLogger = loggerFactory.CreateLogger("Server"); var clientLogger = loggerFactory.CreateLogger("Client"); /* create Modbus TCP server */ using var server = new ModbusTcpServer(serverLogger) { // see 'RegistersChanged' event below EnableRaisingEvents = true }; /* subscribe to the 'RegistersChanged' event (in case you need it) */ server.RegistersChanged += (sender, registerAddresses) => { // the variable 'registerAddresses' contains a list of modified register addresses }; /* create Modbus TCP client */ var client = new ModbusTcpClient(); /* run Modbus TCP server */ var cts = new CancellationTokenSource(); var task_server = Task.Run(async() => { server.Start(); serverLogger.LogInformation("Server started."); while (!cts.IsCancellationRequested) { // lock is required to synchronize buffer access between this application and one or more Modbus clients lock (server.Lock) { DoServerWork(server); } // update server register content once per second await Task.Delay(TimeSpan.FromSeconds(1)); } }, cts.Token); /* run Modbus TCP client */ var task_client = Task.Run(() => { client.Connect(); try { DoClientWork(client, clientLogger); } catch (Exception ex) { clientLogger.LogError(ex.Message); } client.Disconnect(); Console.WriteLine("Tests finished. Press any key to continue."); Console.ReadKey(true); }); // wait for client task to finish await task_client; // stop server cts.Cancel(); await task_server; server.Stop(); serverLogger.LogInformation("Server stopped."); }
static async Task Main(string[] args) { string SENTRON_IP = Environment.GetEnvironmentVariable("SENTRON_IP"); string SENTRON_ID = Environment.GetEnvironmentVariable("SENTRON_ID"); string INFLUXDB_IP = Environment.GetEnvironmentVariable("INFLUXDB_IP"); string INFLUXDB_PORT = Environment.GetEnvironmentVariable("INFLUXDB_PORT"); string INFLUXDB_DATABASE = Environment.GetEnvironmentVariable("INFLUXDB_DATABASE"); string INFLUXDB_USERNAME = Environment.GetEnvironmentVariable("INFLUXDB_USERNAME"); string INFLUXDB_PASSWORD = Environment.GetEnvironmentVariable("INFLUXDB_PASSWORD"); int RETRY, READING; if (!Int32.TryParse(Environment.GetEnvironmentVariable("RETRY"), out RETRY)) { Console.WriteLine("Invalid RETRY using 10"); RETRY = 10 * 1000; } else { RETRY = RETRY * 1000; } if (!Int32.TryParse(Environment.GetEnvironmentVariable("READING"), out READING)) { Console.WriteLine("Invalid READING using 5"); READING = 5 * 1000; } else { READING = READING * 1000; } string statusURLString = "http://" + SENTRON_IP + "/"; string influxDbURL = "http://" + INFLUXDB_IP + ":" + INFLUXDB_PORT; Console.WriteLine("Running with below parameters"); Console.WriteLine("\tSENTRON_IP {0}", SENTRON_IP); Console.WriteLine("\tSENTRON_ID {0}", SENTRON_ID); Console.WriteLine("\tINFLUXDB_IP {0}", INFLUXDB_IP); Console.WriteLine("\tINFLUXDB_PORT {0}", INFLUXDB_PORT); Console.WriteLine("\tINFLUXDB_DATABASE {0}", INFLUXDB_DATABASE); Console.WriteLine("\tINFLUXDB_USERNAME {0}", INFLUXDB_USERNAME); Console.WriteLine("\tINFLUXDB_PASSWORD {0}", INFLUXDB_PASSWORD); Console.WriteLine("\tRETRY {0}", RETRY / 1000); Console.WriteLine("\tREADING {0}", READING / 1000); Console.WriteLine("\n\nUsing Status URL : {0}", statusURLString); Console.WriteLine("Using InfluxDB URL : {0}", influxDbURL); while (true) { InfluxDBClient influxClient = new InfluxDBClient(influxDbURL, INFLUXDB_USERNAME, INFLUXDB_PASSWORD); try { while (true) { byte unitIdentifier = 0xFF; client.Connect(IPAddress.Parse(SENTRON_IP)); var data = client.ReadHoldingRegisters(unitIdentifier, 200, 122).ToArray(); var valMixed = new InfluxDatapoint <InfluxValueField>(); valMixed.UtcTimestamp = DateTime.UtcNow; valMixed.Tags.Add("id", SENTRON_ID); valMixed.MeasurementName = "METER_DATA"; valMixed.Precision = TimePrecision.Seconds; var Va = ToFloatStart201(data, 201); var Vb = ToFloatStart201(data, 203); var Vc = ToFloatStart201(data, 205); var VN = ToFloatStart201(data, 207); valMixed.Fields.Add("Va", new InfluxValueField(Va)); valMixed.Fields.Add("Vb", new InfluxValueField(Vb)); valMixed.Fields.Add("Vc", new InfluxValueField(Vc)); valMixed.Fields.Add("VN", new InfluxValueField(VN)); var Ia = ToFloatStart201(data, 209); var Ib = ToFloatStart201(data, 211); var Ic = ToFloatStart201(data, 213); var IN = ToFloatStart201(data, 215); valMixed.Fields.Add("Ia", new InfluxValueField(Ia)); valMixed.Fields.Add("Ib", new InfluxValueField(Ib)); valMixed.Fields.Add("Ic", new InfluxValueField(Ic)); valMixed.Fields.Add("IN", new InfluxValueField(IN)); var Vab = ToFloatStart201(data, 217); var Vbc = ToFloatStart201(data, 219); var Vca = ToFloatStart201(data, 221); valMixed.Fields.Add("Vab", new InfluxValueField(Vab)); valMixed.Fields.Add("Vbc", new InfluxValueField(Vbc)); valMixed.Fields.Add("Vca", new InfluxValueField(Vca)); var Vavg = ToFloatStart201(data, 223); var Iavg = ToFloatStart201(data, 225); valMixed.Fields.Add("Vavg", new InfluxValueField(Vavg)); valMixed.Fields.Add("Iavg", new InfluxValueField(Iavg)); var Pa = ToFloatStart201(data, 227); var Pb = ToFloatStart201(data, 229); var Pc = ToFloatStart201(data, 231); var P = ToFloatStart201(data, 233); valMixed.Fields.Add("Pa", new InfluxValueField(Pa)); valMixed.Fields.Add("Pb", new InfluxValueField(Pb)); valMixed.Fields.Add("Pc", new InfluxValueField(Pc)); valMixed.Fields.Add("P", new InfluxValueField(P)); var Qa = ToFloatStart201(data, 235); var Qb = ToFloatStart201(data, 237); var Qc = ToFloatStart201(data, 239); var Q = ToFloatStart201(data, 241); var Sa = ToFloatStart201(data, 243); var Sb = ToFloatStart201(data, 245); var Sc = ToFloatStart201(data, 247); var S = ToFloatStart201(data, 249); var cos_phi_a = ToFloatStart201(data, 251); var cos_phi_b = ToFloatStart201(data, 253); var cos_phi_c = ToFloatStart201(data, 255); var cos_phi = ToFloatStart201(data, 257); var PFa = ToFloatStart201(data, 259); var PFb = ToFloatStart201(data, 261); var PFc = ToFloatStart201(data, 263); var PF = ToFloatStart201(data, 265); valMixed.Fields.Add("PFa", new InfluxValueField(PFa)); valMixed.Fields.Add("PFb", new InfluxValueField(PFb)); valMixed.Fields.Add("PFc", new InfluxValueField(PFc)); valMixed.Fields.Add("PF", new InfluxValueField(PF)); var phi_a = ToFloatStart201(data, 267); var phi_b = ToFloatStart201(data, 269); var phi_c = ToFloatStart201(data, 271); var phi = ToFloatStart201(data, 273); var f = ToFloatStart201(data, 275); var U2 = ToFloatStart201(data, 277); var THDS_Va_Vab = ToFloatStart201(data, 295); var THDS_Vb_Vbc = ToFloatStart201(data, 297); var THDS_Vc_Vca = ToFloatStart201(data, 299); var THDS_Ia = ToFloatStart201(data, 301); var THDS_Ib = ToFloatStart201(data, 303); var THDS_Ic = ToFloatStart201(data, 305); var V_phi_12 = ToFloatStart201(data, 307); var V_phi_13 = ToFloatStart201(data, 309); var I_phi_12 = ToFloatStart201(data, 311); var I_phi_13 = ToFloatStart201(data, 313); var Q1a = ToFloatStart201(data, 315); var Q1b = ToFloatStart201(data, 317); var Q1c = ToFloatStart201(data, 319); var Q1 = ToFloatStart201(data, 321); var r = await influxClient.PostPointAsync(INFLUXDB_DATABASE, valMixed); Console.WriteLine(r); Thread.Sleep(READING); } } catch (Exception e) { Console.WriteLine("\nException Caught!"); Console.WriteLine("Message :{0} ", e.Message); } client.Disconnect(); influxClient.Dispose(); Thread.Sleep(RETRY); } }