Contains the conversion methods to convert DWord from S7 plc to C#.
Ejemplo n.º 1
0
        private static System.DateTime FromByteArrayImpl(byte[] bytes)
        {
            if (bytes.Length != TypeLengthInBytes)
            {
                throw new ArgumentOutOfRangeException(nameof(bytes), bytes.Length,
                                                      $"Parsing a DateTimeLong requires exactly 12 bytes of input data, input data is {bytes.Length} bytes long.");
            }


            var year      = AssertRangeInclusive(Word.FromBytes(bytes[1], bytes[0]), 1970, 2262, "year");
            var month     = AssertRangeInclusive(bytes[2], 1, 12, "month");
            var day       = AssertRangeInclusive(bytes[3], 1, 31, "day of month");
            var dayOfWeek = AssertRangeInclusive(bytes[4], 1, 7, "day of week");
            var hour      = AssertRangeInclusive(bytes[5], 0, 23, "hour");
            var minute    = AssertRangeInclusive(bytes[6], 0, 59, "minute");
            var second    = AssertRangeInclusive(bytes[7], 0, 59, "second");

            ;

            var nanoseconds = AssertRangeInclusive <uint>(DWord.FromBytes(bytes[11], bytes[10], bytes[9], bytes[8]), 0,
                                                          999999999, "nanoseconds");

            var time = new System.DateTime(year, month, day, hour, minute, second);

            return(time.AddTicks(nanoseconds / 100));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Converts a S7 DWord to double
        /// </summary>
        public static double FromDWord(UInt32 value)
        {
            byte[] b = DWord.ToByteArray(value);
            double d = FromByteArray(b);

            return(d);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Converts a S7 DWord to float
        /// </summary>
        public static float FromDWord(UInt32 value)
        {
            byte[] b = DWord.ToByteArray(value);
            float  d = FromByteArray(b);

            return(d);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Converts a <see cref="T:System.DateTime" /> value to a byte array.
        /// </summary>
        /// <param name="dateTime">The DateTime value to convert.</param>
        /// <returns>A byte array containing the S7 DateTimeLong representation of <paramref name="dateTime" />.</returns>
        /// <exception cref="ArgumentOutOfRangeException">
        /// Thrown when the value of
        /// <paramref name="dateTime" /> is before <see cref="P:SpecMinimumDateTime" />
        /// or after <see cref="P:SpecMaximumDateTime" />.
        /// </exception>
        public static byte[] ToByteArray(System.DateTime dateTime)
        {
            if (dateTime < SpecMinimumDateTime)
            {
                throw new ArgumentOutOfRangeException(nameof(dateTime), dateTime,
                                                      $"Date time '{dateTime}' is before the minimum '{SpecMinimumDateTime}' supported in S7 DateTimeLong representation.");
            }

            if (dateTime > SpecMaximumDateTime)
            {
                throw new ArgumentOutOfRangeException(nameof(dateTime), dateTime,
                                                      $"Date time '{dateTime}' is after the maximum '{SpecMaximumDateTime}' supported in S7 DateTimeLong representation.");
            }

            var stream = new MemoryStream(TypeLengthInBytes);

            // Convert Year
            stream.Write(Word.ToByteArray(Convert.ToUInt16(dateTime.Year)), 0, 2);

            // Convert Month
            stream.WriteByte(Convert.ToByte(dateTime.Month));

            // Convert Day
            stream.WriteByte(Convert.ToByte(dateTime.Day));

            // Convert WeekDay. NET DateTime starts with Sunday = 0, while S7DT has Sunday = 1.
            stream.WriteByte(Convert.ToByte(dateTime.DayOfWeek + 1));

            // Convert Hour
            stream.WriteByte(Convert.ToByte(dateTime.Hour));

            // Convert Minutes
            stream.WriteByte(Convert.ToByte(dateTime.Minute));

            // Convert Seconds
            stream.WriteByte(Convert.ToByte(dateTime.Second));

            // Convert Nanoseconds. Net DateTime has a representation of 1 Tick = 100ns.
            // Thus First take the ticks Mod 1 Second (1s = 10'000'000 ticks), and then Convert to nanoseconds.
            stream.Write(DWord.ToByteArray(Convert.ToUInt32(dateTime.Ticks % 10000000 * 100)), 0, 4);

            return(stream.ToArray());
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Creates a struct of a specified type by an array of bytes.
        /// </summary>
        /// <param name="structType">The struct type</param>
        /// <param name="bytes">The array of bytes</param>
        /// <returns>The object depending on the struct type or null if fails(array-length != struct-length</returns>
        public static object FromBytes(Type structType, byte[] bytes)
        {
            if (bytes == null)
            {
                return(null);
            }

            if (bytes.Length != GetStructSize(structType))
            {
                return(null);
            }

            // and decode it
            int    bytePos     = 0;
            int    bitPos      = 0;
            double numBytes    = 0.0;
            object structValue = Activator.CreateInstance(structType);

            System.Reflection.FieldInfo[] infos = structValue.GetType().GetFields();
            foreach (System.Reflection.FieldInfo info in infos)
            {
                switch (info.FieldType.Name)
                {
                case "Boolean":
                    // get the value
                    bytePos = (int)Math.Floor(numBytes);
                    bitPos  = (int)((numBytes - (double)bytePos) / 0.125);
                    if ((bytes[bytePos] & (int)Math.Pow(2, bitPos)) != 0)
                    {
                        info.SetValue(structValue, true);
                    }
                    else
                    {
                        info.SetValue(structValue, false);
                    }
                    numBytes += 0.125;
                    break;

                case "Byte":
                    numBytes = Math.Ceiling(numBytes);
                    info.SetValue(structValue, (byte)(bytes[(int)numBytes]));
                    numBytes++;
                    break;

                case "Int16":
                    numBytes = Math.Ceiling(numBytes);
                    if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
                    {
                        numBytes++;
                    }
                    // hier auswerten
                    ushort source = Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes]);
                    info.SetValue(structValue, source.ConvertToShort());
                    numBytes += 2;
                    break;

                case "UInt16":
                    numBytes = Math.Ceiling(numBytes);
                    if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
                    {
                        numBytes++;
                    }
                    // hier auswerten
                    info.SetValue(structValue, Word.FromBytes(bytes[(int)numBytes + 1],
                                                              bytes[(int)numBytes]));
                    numBytes += 2;
                    break;

                case "Int32":
                    numBytes = Math.Ceiling(numBytes);
                    if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
                    {
                        numBytes++;
                    }
                    // hier auswerten
                    uint sourceUInt = DWord.FromBytes(bytes[(int)numBytes + 3],
                                                      bytes[(int)numBytes + 2],
                                                      bytes[(int)numBytes + 1],
                                                      bytes[(int)numBytes + 0]);
                    info.SetValue(structValue, sourceUInt.ConvertToInt());
                    numBytes += 4;
                    break;

                case "UInt32":
                    numBytes = Math.Ceiling(numBytes);
                    if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
                    {
                        numBytes++;
                    }
                    // hier auswerten
                    info.SetValue(structValue, DWord.FromBytes(bytes[(int)numBytes],
                                                               bytes[(int)numBytes + 1],
                                                               bytes[(int)numBytes + 2],
                                                               bytes[(int)numBytes + 3]));
                    numBytes += 4;
                    break;

                case "Double":
                    numBytes = Math.Ceiling(numBytes);
                    if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
                    {
                        numBytes++;
                    }
                    // hier auswerten
                    info.SetValue(structValue, Double.FromByteArray(new byte[] { bytes[(int)numBytes],
                                                                                 bytes[(int)numBytes + 1],
                                                                                 bytes[(int)numBytes + 2],
                                                                                 bytes[(int)numBytes + 3] }));
                    numBytes += 4;
                    break;
                }
            }
            return(structValue);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Creates a byte array depending on the struct type.
        /// </summary>
        /// <param name="structValue">The struct object</param>
        /// <returns>A byte array or null if fails.</returns>
        public static byte[] ToBytes(object structValue)
        {
            Type type = structValue.GetType();

            int size = Struct.GetStructSize(type);

            byte[] bytes  = new byte[size];
            byte[] bytes2 = null;

            int    bytePos  = 0;
            int    bitPos   = 0;
            double numBytes = 0.0;

            System.Reflection.FieldInfo[] infos = type.GetFields();
            foreach (System.Reflection.FieldInfo info in infos)
            {
                bytes2 = null;
                switch (info.FieldType.Name)
                {
                case "Boolean":
                    // get the value
                    bytePos = (int)Math.Floor(numBytes);
                    bitPos  = (int)((numBytes - (double)bytePos) / 0.125);
                    if ((bool)info.GetValue(structValue))
                    {
                        bytes[bytePos] |= (byte)Math.Pow(2, bitPos);                // is true
                    }
                    else
                    {
                        bytes[bytePos] &= (byte)(~(byte)Math.Pow(2, bitPos));       // is false
                    }
                    numBytes += 0.125;
                    break;

                case "Byte":
                    numBytes       = (int)Math.Ceiling(numBytes);
                    bytePos        = (int)numBytes;
                    bytes[bytePos] = (byte)info.GetValue(structValue);
                    numBytes++;
                    break;

                case "Int16":
                    bytes2 = Int.ToByteArray((Int16)info.GetValue(structValue));
                    break;

                case "UInt16":
                    bytes2 = Word.ToByteArray((UInt16)info.GetValue(structValue));
                    break;

                case "Int32":
                    bytes2 = DInt.ToByteArray((Int32)info.GetValue(structValue));
                    break;

                case "UInt32":
                    bytes2 = DWord.ToByteArray((UInt32)info.GetValue(structValue));
                    break;

                case "Double":
                    bytes2 = Double.ToByteArray((double)info.GetValue(structValue));
                    break;
                }
                if (bytes2 != null)
                {
                    // add them
                    numBytes = Math.Ceiling(numBytes);
                    if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
                    {
                        numBytes++;
                    }
                    bytePos = (int)numBytes;
                    for (int bCnt = 0; bCnt < bytes2.Length; bCnt++)
                    {
                        bytes[bytePos + bCnt] = bytes2[bCnt];
                    }
                    numBytes += bytes2.Length;
                }
            }
            return(bytes);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Creates a struct of a specified type by an array of bytes.
        /// </summary>
        /// <param name="sourceClass"></param>
        /// <param name="classType">The struct type</param>
        /// <param name="bytes">The array of bytes</param>
        /// <returns>The object depending on the struct type or null if fails(array-length != struct-length</returns>
        public static void FromBytes(object sourceClass, Type classType, byte[] bytes)
        {
            if (bytes == null)
            {
                return;
            }

            if (bytes.Length != GetClassSize(classType))
            {
                return;
            }

            // and decode it
            int    bytePos  = 0;
            int    bitPos   = 0;
            double numBytes = 0.0;


            var properties = sourceClass.GetType().GetProperties();

            foreach (var property in properties)
            {
                switch (property.PropertyType.Name)
                {
                case "Boolean":
                    // get the value
                    bytePos = (int)Math.Floor(numBytes);
                    bitPos  = (int)((numBytes - (double)bytePos) / 0.125);
                    if ((bytes[bytePos] & (int)Math.Pow(2, bitPos)) != 0)
                    {
                        property.SetValue(sourceClass, true, null);
                    }
                    else
                    {
                        property.SetValue(sourceClass, false, null);
                    }
                    numBytes += 0.125;
                    break;

                case "Byte":
                    numBytes = Math.Ceiling(numBytes);
                    property.SetValue(sourceClass, (byte)(bytes[(int)numBytes]), null);
                    numBytes++;
                    break;

                case "Int16":
                    numBytes = Math.Ceiling(numBytes);
                    if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
                    {
                        numBytes++;
                    }
                    // hier auswerten
                    ushort source = Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes]);
                    property.SetValue(sourceClass, source.ConvertToShort(), null);
                    numBytes += 2;
                    break;

                case "UInt16":
                    numBytes = Math.Ceiling(numBytes);
                    if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
                    {
                        numBytes++;
                    }
                    // hier auswerten
                    property.SetValue(sourceClass, Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes]), null);
                    numBytes += 2;
                    break;

                case "Int32":
                    numBytes = Math.Ceiling(numBytes);
                    if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
                    {
                        numBytes++;
                    }
                    // hier auswerten
                    uint sourceUInt = DWord.FromBytes(bytes[(int)numBytes + 3],
                                                      bytes[(int)numBytes + 2],
                                                      bytes[(int)numBytes + 1],
                                                      bytes[(int)numBytes + 0]);
                    property.SetValue(sourceClass, sourceUInt.ConvertToInt(), null);
                    numBytes += 4;
                    break;

                case "UInt32":
                    numBytes = Math.Ceiling(numBytes);
                    if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
                    {
                        numBytes++;
                    }
                    // hier auswerten
                    property.SetValue(sourceClass, DWord.FromBytes(bytes[(int)numBytes],
                                                                   bytes[(int)numBytes + 1],
                                                                   bytes[(int)numBytes + 2],
                                                                   bytes[(int)numBytes + 3]), null);
                    numBytes += 4;
                    break;

                case "Double":
                    numBytes = Math.Ceiling(numBytes);
                    if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
                    {
                        numBytes++;
                    }
                    // hier auswerten
                    property.SetValue(sourceClass, Double.FromByteArray(new byte[] { bytes[(int)numBytes],
                                                                                     bytes[(int)numBytes + 1],
                                                                                     bytes[(int)numBytes + 2],
                                                                                     bytes[(int)numBytes + 3] }), null);
                    numBytes += 4;
                    break;

                default:
                    var buffer = new byte[GetClassSize(property.PropertyType)];
                    if (buffer.Length == 0)
                    {
                        continue;
                    }
                    Buffer.BlockCopy(bytes, (int)Math.Ceiling(numBytes), buffer, 0, buffer.Length);
                    var propClass = Activator.CreateInstance(property.PropertyType);
                    FromBytes(propClass, property.PropertyType, buffer);
                    property.SetValue(sourceClass, propClass, null);
                    numBytes += buffer.Length;
                    break;
                }
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Creates a byte array depending on the struct type.
        /// </summary>
        /// <param name="sourceClass">The struct object</param>
        /// <returns>A byte array or null if fails.</returns>
        public static byte[] ToBytes(object sourceClass)
        {
            Type type = sourceClass.GetType();

            int size = GetClassSize(type);

            byte[] bytes  = new byte[size];
            byte[] bytes2 = null;

            int    bytePos  = 0;
            int    bitPos   = 0;
            double numBytes = 0.0;

            var properties = sourceClass.GetType().GetProperties();

            foreach (var property in properties)
            {
                bytes2 = null;
                switch (property.PropertyType.Name)
                {
                case "Boolean":
                    // get the value
                    bytePos = (int)Math.Floor(numBytes);
                    bitPos  = (int)((numBytes - (double)bytePos) / 0.125);
                    if ((bool)property.GetValue(sourceClass, null))
                    {
                        bytes[bytePos] |= (byte)Math.Pow(2, bitPos);                // is true
                    }
                    else
                    {
                        bytes[bytePos] &= (byte)(~(byte)Math.Pow(2, bitPos));       // is false
                    }
                    numBytes += 0.125;
                    break;

                case "Byte":
                    numBytes       = (int)Math.Ceiling(numBytes);
                    bytePos        = (int)numBytes;
                    bytes[bytePos] = (byte)property.GetValue(sourceClass, null);
                    numBytes++;
                    break;

                case "Int16":
                    bytes2 = Int.ToByteArray((Int16)property.GetValue(sourceClass, null));
                    break;

                case "UInt16":
                    bytes2 = Word.ToByteArray((UInt16)property.GetValue(sourceClass, null));
                    break;

                case "Int32":
                    bytes2 = DInt.ToByteArray((Int32)property.GetValue(sourceClass, null));
                    break;

                case "UInt32":
                    bytes2 = DWord.ToByteArray((UInt32)property.GetValue(sourceClass, null));
                    break;

                case "Double":
                    bytes2 = Double.ToByteArray((double)property.GetValue(sourceClass, null));
                    break;
                }
                if (bytes2 != null)
                {
                    // add them
                    numBytes = Math.Ceiling(numBytes);
                    if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
                    {
                        numBytes++;
                    }
                    bytePos = (int)numBytes;
                    for (int bCnt = 0; bCnt < bytes2.Length; bCnt++)
                    {
                        bytes[bytePos + bCnt] = bytes2[bCnt];
                    }
                    numBytes += bytes2.Length;
                }
            }
            return(bytes);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Creates a struct of a specified type by an array of bytes.
        /// </summary>
        /// <param name="sourceClass"></param>
        /// <param name="classType">The struct type</param>
        /// <param name="bytes">The array of bytes</param>
        /// <returns>The object depending on the struct type or null if fails(array-length != struct-length</returns>
        public static void FromBytes(object sourceClass, Type classType, byte[] bytes)
        {
            if (bytes == null)
                return;

            if (bytes.Length != GetClassSize(classType))
                return;

            // and decode it
            int bytePos = 0;
            int bitPos = 0;
            double numBytes = 0.0;


            var properties = sourceClass.GetType().GetProperties();
            foreach (var property in properties)
            {
                switch (property.PropertyType.Name)
                {
                    case "Boolean":
                        // get the value
                        bytePos = (int)Math.Floor(numBytes);
                        bitPos = (int)((numBytes - (double)bytePos) / 0.125);
                        if ((bytes[bytePos] & (int)Math.Pow(2, bitPos)) != 0)
                            property.SetValue(sourceClass, true, null);
                        else
                            property.SetValue(sourceClass, false, null);
                        numBytes += 0.125;
                        break;
                    case "Byte":
                        numBytes = Math.Ceiling(numBytes);
                        property.SetValue(sourceClass, (byte)(bytes[(int)numBytes]), null);
                        numBytes++;
                        break;
                    case "Int16":
                        numBytes = Math.Ceiling(numBytes);
                        if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
                            numBytes++;
                        // hier auswerten
                        ushort source = Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes]);
                        property.SetValue(sourceClass, source.ConvertToShort(), null);
                        numBytes += 2;
                        break;
                    case "UInt16":
                        numBytes = Math.Ceiling(numBytes);
                        if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
                            numBytes++;
                        // hier auswerten
                        property.SetValue(sourceClass, Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes]), null);
                        numBytes += 2;
                        break;
                    case "Int32":
                        numBytes = Math.Ceiling(numBytes);
                        if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
                            numBytes++;
                        // hier auswerten
                        uint sourceUInt = DWord.FromBytes(bytes[(int)numBytes + 3],
                                                                           bytes[(int)numBytes + 2],
                                                                           bytes[(int)numBytes + 1],
                                                                           bytes[(int)numBytes + 0]);
                        property.SetValue(sourceClass, sourceUInt.ConvertToInt(), null);
                        numBytes += 4;
                        break;
                    case "UInt32":
                        numBytes = Math.Ceiling(numBytes);
                        if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
                            numBytes++;
                        // hier auswerten
                        property.SetValue(sourceClass, DWord.FromBytes(bytes[(int)numBytes],
                                                                           bytes[(int)numBytes + 1],
                                                                           bytes[(int)numBytes + 2],
                                                                           bytes[(int)numBytes + 3]), null);
                        numBytes += 4;
                        break;
                    case "Double":
                        numBytes = Math.Ceiling(numBytes);
                        if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
                            numBytes++;
                        // hier auswerten
                        property.SetValue(sourceClass, Double.FromByteArray(new byte[] { bytes[(int)numBytes],
                                                                           bytes[(int)numBytes + 1],
                                                                           bytes[(int)numBytes + 2],
                                                                           bytes[(int)numBytes + 3] }), null);
                        numBytes += 4;
                        break;
                }
            }
        }