예제 #1
0
        public void FC03Test()
        {
            // Arrange
            var endpoint = EndpointSource.GetNext();

            var server = new ModbusTcpServer();

            server.Start(endpoint);

            lock (server.Lock)
            {
                var buffer = server.GetHoldingRegisterBuffer <float>();

                buffer[6] = 65.455F;
                buffer[7] = 24;
                buffer[8] = 25;
            }

            var client = new ModbusTcpClient();

            client.Connect(endpoint);

            // Act
            var actual = client.ReadHoldingRegisters <float>(0, 2, 10);

            // Assert
            var expected = _array;

            Assert.True(expected.SequenceEqual(actual.ToArray()));
        }
예제 #2
0
        private bool ReadParams(HVAC hvac)
        {
            //1.读取保持寄存器的数据,从40000 读到 40046,寄存器数量48
            byte[] b1 = objTcpClient.ReadHoldingRegisters(0, 48, 0);
            //2.处理数据
            if (b1 != null)
            {
                //遍历modbus地址为4区的param
                foreach (Param item in hvac.Params)
                {
                    if (item.ModubsAddr[0] == '4')    //4xxxx
                    {
                        // 40002 => 002 => 4
                        int    start = int.Parse(item.ModubsAddr.Substring(2, 3)) * 2;
                        byte[] data  = new byte[4] {
                            b1[start], b1[start + 1], b1[start + 2], b1[start + 3]
                        };
                        data       = Common.DataConverter.ReverseFormatDCBA(data);
                        item.Value = BitConverter.ToSingle(data, 0);    //startIndex处的字节为高位字节
                    }
                }
            }
            else
            {
                return(false);
            }

            //3.读取输入线圈状态,从00000读到00003,共4个线圈,起始地址为0
            byte[] b2 = objTcpClient.ReadCoilStatus(0, 4, 0);
            if (b2 != null)
            {
                foreach (Param item in hvac.Params)
                {
                    if (item.ModubsAddr[0] == '0')
                    {
                        //获取该变量的相对地址,相对地址为绝对地址减去读取起始地址
                        //此处读取起始地址为0,则相对地址即为modbus绝对地址的尾数
                        int i = int.Parse(item.ModubsAddr.Substring(2, 3));

                        //将第0个字节转换成2进制形式的字符串 11011010
                        string str = Convert.ToString(b2[0], 2).PadLeft(8, '0');

                        char c = str[7 - i];

                        item.Value = (c == '1' ? 1f : 0f);
                    }
                }
                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #3
0
        public void ThrowsIfZeroBytesAreRequested()
        {
            // Arrange
            _server.Start(_endpoint);

            var client = new ModbusTcpClient();

            client.Connect(_endpoint);

            // Act
            Action action = () => client.ReadHoldingRegisters <byte>(0, 0, 0);

            // Assert
            Assert.Throws <ModbusException>(action);
        }
예제 #4
0
        public void ThrowsIfOddNumberOfBytesIsRequested()
        {
            // Arrange
            _server.Start(_endpoint);

            var client = new ModbusTcpClient();

            client.Connect(_endpoint);

            // Act
            Action action = () => client.ReadHoldingRegisters <byte>(0, 0, 3);

            // Assert

            Assert.Throws <ArgumentOutOfRangeException>(action);
        }
예제 #5
0
        public void CanReadMaximumNumberOfRegisters()
        {
            // Arrange
            var endpoint = EndpointSource.GetNext();

            using var server = new ModbusTcpServer();
            server.Start(endpoint);

            var client = new ModbusTcpClient();

            client.Connect(endpoint);

            // Act
            client.ReadHoldingRegisters <ushort>(0, 0, 125);
            client.ReadInputRegisters <ushort>(0, 0, 125);
        }
예제 #6
0
        public void ArraySizeIsCorrectForBooleanInput()
        {
            // Arrange
            _server.Start(_endpoint);

            var client = new ModbusTcpClient();

            client.Connect(_endpoint);

            // Act
            var actual = client.ReadHoldingRegisters <bool>(0, 0, 10).ToArray().Count();

            // Assert
            var expected = 10;

            Assert.True(actual == expected);
        }
예제 #7
0
        public void ThrowsIfZeroBytesAreRequested()
        {
            // Arrange
            var endpoint = EndpointSource.GetNext();

            using var server = new ModbusTcpServer();
            server.Start(endpoint);

            var client = new ModbusTcpClient();

            client.Connect(endpoint);

            // Act
            Action action = () => client.ReadHoldingRegisters <byte>(0, 0, 0);

            // Assert
            Assert.Throws <ModbusException>(action);
        }
예제 #8
0
        static void DoClientWork(ModbusTcpClient client, ILogger logger)
        {
            Span <byte> data;

            var sleepTime       = TimeSpan.FromMilliseconds(100);
            var unitIdentifier  = (byte)0xFF;
            var startingAddress = (ushort)0;
            var registerAddress = (ushort)0;

            // ReadHoldingRegisters = 0x03,        // FC03
            data = client.ReadHoldingRegisters(unitIdentifier, startingAddress, 10);
            logger.LogInformation("FC03 - ReadHoldingRegisters: Done");
            Thread.Sleep(sleepTime);

            // WriteMultipleRegisters = 0x10,      // FC16
            client.WriteMultipleRegisters(unitIdentifier, startingAddress, new byte[] { 10, 00, 20, 00, 30, 00, 255, 00, 255, 01 });
            logger.LogInformation("FC16 - WriteMultipleRegisters: Done");
            Thread.Sleep(sleepTime);

            // ReadCoils = 0x01,                   // FC01
            data = client.ReadCoils(unitIdentifier, startingAddress, 10);
            logger.LogInformation("FC01 - ReadCoils: Done");
            Thread.Sleep(sleepTime);

            // ReadDiscreteInputs = 0x02,          // FC02
            data = client.ReadDiscreteInputs(unitIdentifier, startingAddress, 10);
            logger.LogInformation("FC02 - ReadDiscreteInputs: Done");
            Thread.Sleep(sleepTime);

            // ReadInputRegisters = 0x04,          // FC04
            data = client.ReadInputRegisters(unitIdentifier, startingAddress, 10);
            logger.LogInformation("FC04 - ReadInputRegisters: Done");
            Thread.Sleep(sleepTime);

            // WriteSingleCoil = 0x05,             // FC05
            client.WriteSingleCoil(unitIdentifier, registerAddress, true);
            logger.LogInformation("FC05 - WriteSingleCoil: Done");
            Thread.Sleep(sleepTime);

            // WriteSingleRegister = 0x06,         // FC06
            client.WriteSingleRegister(unitIdentifier, registerAddress, new byte[] { 65, 67 });
            logger.LogInformation("FC06 - WriteSingleRegister: Done");
        }
예제 #9
0
        public void ThrowsWhenReadingTooManyRegisters()
        {
            // Arrange
            var endpoint = EndpointSource.GetNext();

            using var server = new ModbusTcpServer();
            server.Start(endpoint);

            var client = new ModbusTcpClient();

            client.Connect(endpoint);

            // Act
            Action action1 = () => client.ReadHoldingRegisters <ushort>(0, 0, 126);
            Action action2 = () => client.ReadInputRegisters <ushort>(0, 0, 126);

            // Assert
            Assert.Throws <ModbusException>(action1);
            Assert.Throws <ModbusException>(action2);
        }
예제 #10
0
        public void ArraySizeIsCorrectForFloatInput()
        {
            // Arrange
            var endpoint = EndpointSource.GetNext();

            using var server = new ModbusTcpServer();
            server.Start(endpoint);

            var client = new ModbusTcpClient();

            client.Connect(endpoint);

            // Act
            var actual = client.ReadHoldingRegisters <float>(0, 0, 10).ToArray().Count();

            // Assert
            var expected = 10;

            Assert.True(actual == expected);
        }
 public byte[] Read(byte unit, ushort register)
 {
     return(_connection.ReadHoldingRegisters <byte>(unit, register, 4).ToArray());
 }
        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);
            }
        }