Пример #1
0
 /// <summary>
 /// Асинхронно изменить значение переменной без подтверждения успеха внесения изменений.
 /// </summary>
 /// <param name="target">Адрес устройства, на котором требуется изменить значение переменной.</param>
 /// <param name="id">Идентификатор переменной.</param>
 /// <param name="valueType">Тип значения.</param>
 /// <param name="value">Записываемое значение.</param>
 public async Task WriteValueAsync(Address target, int id, NmsValueType valueType, object value)
 {
     //Contract.Requires(!IsDisposed);
     //Contract.Requires(target != null);
     //Contract.Requires(value != null);
     var write = new NmsWrite(target, id, valueType, value, false);
     await OutgoingMessages.SendAsync(write);
 }
Пример #2
0
        /// <summary>
        /// Изменить значение переменной без подтверждения успеха внесения изменений.
        /// </summary>
        /// <param name="target">Адрес устройства, на котором требуется изменить значение переменной.</param>
        /// <param name="id">Идентификатор переменной.</param>
        /// <param name="valueType">Тип значения.</param>
        /// <param name="value">Записываемое значение.</param>
        public void WriteValue(Address target, int id, NmsValueType valueType, object value)
        {
            Contract.Requires(!IsDisposed);
            Contract.Requires(target != null);
            Contract.Requires(value != null);
            var write = new NmsWrite(target, id, valueType, value, false);

            OutgoingMessages.Post(write);
        }
Пример #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="NmsWrite"/> class.
 /// </summary>
 /// <param name="destanation">Адрес получателя сообщения.</param>
 /// <param name="id">Идентификатор переменной.</param>
 /// <param name="valueType">Тип значения.</param>
 /// <param name="value">Записываемое значение.</param>
 /// <param name="waitResponse"><c>true</c> - если требуется подтверждение записи.</param>
 /// <param name="priority">Приоритет.</param>
 public NmsWrite(
     Address destanation,
     int id,
     NmsValueType valueType,
     object value,
     bool waitResponse     = true,
     PriorityType priority = PriorityType.Normal)
     : this(Address.Empty, destanation, id, valueType, value, waitResponse, priority)
 {
     Contract.Requires(destanation != null);
     Contract.Requires(value != null);
 }
Пример #4
0
        /// <summary>
        /// Асинхронно изменить значение переменной с подтверждением успеха внесения изменений.
        /// </summary>
        /// <param name="target">Адрес устройства, на котором требуется изменить значение переменной.</param>
        /// <param name="id">Идентификатор переменной.</param>
        /// <param name="valueType">Тип значения.</param>
        /// <param name="value">Записываемое значение.</param>
        /// <param name="options">Параметры NiBUS-операции.</param>
        /// <returns>
        ///  <see cref="Task"/> асинхронная операция.
        /// </returns>
        public async Task WriteValueConfirmedAsync(
            Address target,
            int id,
            NmsValueType valueType,
            object value,
            NibusOptions options = null)
        {
            Contract.Requires(!IsDisposed);
            Contract.Requires(target != null);
            Contract.Requires(target.Type == AddressType.Hardware || target.Type == AddressType.Net);
            Contract.Requires(value != null);
            var write = new NmsWrite(target, id, valueType, value);

            await WaitForNmsResponseAsync(write, options);
        }
Пример #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="NmsInformationReport"/> class.
 /// </summary>
 /// <param name="source">Адрес источника сообщения.</param>
 /// <param name="id">Идентификатор информационного сообщения. <seealso cref="GameReports"/></param>
 /// <param name="valueType">Тип значения информационного сообщения.</param>
 /// <param name="value">Значение информационного сообщения.</param>
 /// <param name="priority">Приоритет.</param>
 public NmsInformationReport(
     Address source, int id, NmsValueType valueType, object value, PriorityType priority = PriorityType.Normal)
 {
     Contract.Ensures(!IsResponse);
     Contract.Ensures(ServiceType == NmsServiceType.InformationReport);
     Initialize(
         source,
         Address.Broadcast,
         priority,
         NmsServiceType.InformationReport,
         false,
         id,
         false,
         WriteValue(valueType, value));
 }
Пример #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="NmsWrite"/> class.
 /// </summary>
 /// <param name="source">Адрес источника сообщения.</param>
 /// <param name="destanation">Адрес получателя сообщения.</param>
 /// <param name="id">Идентификатор переменной.</param>
 /// <param name="valueType">Тип значения.</param>
 /// <param name="value">Записываемое значение.</param>
 /// <param name="waitResponse"><c>true</c> - если требуется подтверждение записи.</param>
 /// <param name="priority">Приоритет.</param>
 public NmsWrite(Address source, Address destanation, int id, NmsValueType valueType, object value,
                 bool waitResponse = true, PriorityType priority = PriorityType.Normal)
 {
     Contract.Requires(source != null);
     Contract.Requires(destanation != null);
     Contract.Requires(value != null);
     Initialize(
         source,
         destanation,
         priority,
         NmsServiceType.Write,
         waitResponse,
         id,
         false,
         WriteValue(valueType, value));
 }
Пример #7
0
        /// <summary>
        /// Возвращает размер данных указанного типа и возможно значения для массива или строки.
        /// </summary>
        /// <param name="vt">Тип данных.</param>
        /// <param name="value">Значение данных в случае массива или строки.</param>
        /// <returns>Занимаемый размер.</returns>
        public static int GetSizeOf(NmsValueType vt, object value = null)
        {
            switch (vt)
            {
            case NmsValueType.Boolean:
            case NmsValueType.Int8:
            case NmsValueType.UInt8:
                return(1);

            case NmsValueType.Int16:
            case NmsValueType.UInt16:
                return(2);

            case NmsValueType.Int32:
            case NmsValueType.UInt32:
            case NmsValueType.Real32:
                return(4);

            case NmsValueType.Int64:
            case NmsValueType.UInt64:
            case NmsValueType.Real64:
                return(8);

            case NmsValueType.DateTime:
                return(10);

            case NmsValueType.String:
                return(Math.Min(NmsMaxDataLength - 1, (value != null ? ((string)value).Length : 0) + 1));
            }

            if (((byte)vt & (byte)NmsValueType.Array) == 0)
            {
                throw new ArgumentException("Invalid ValueType");
            }

            var arrayType = (NmsValueType)((byte)vt & ((byte)NmsValueType.Array - 1));
            var itemSize  = GetSizeOf(arrayType);

            return(value != null ? ((ICollection)value).Count * itemSize : itemSize);
        }
Пример #8
0
        /// <summary>
        /// Конструктор создания NMS-сообщения сервиса <see cref="NmsServiceType.Read"/>
        /// из низлежащего сообщения <see cref="NibusDatagram"/>.
        /// </summary>
        /// <param name="datagram">Датаграмма.</param>
        /// <remarks>
        /// Минимальный размер длины данных <paramref name="datagram"/> должен быть не меньше размера
        /// заголовка <see cref="NmsMessage.NmsHeaderLength"/> плюс размер NMS-данных.
        /// </remarks>
        /// <seealso cref="NmsMessage.CreateFrom"/>
        /// <exception cref="InvalidNibusDatagram"></exception>
        internal NmsRead(NibusDatagram datagram)
            : base(datagram)
        {
            Contract.Requires(datagram != null);
            Contract.Requires(datagram.ProtocolType == ProtocolType.Nms);
            Contract.Requires(datagram.Data.Count >= NmsHeaderLength);
            Contract.Ensures(ServiceType == NmsServiceType.Read);
            Contract.Assume(ServiceType == NmsServiceType.Read);
            if (!IsResponse)
            {
                return;
            }

            if (datagram.Data.Count < NmsHeaderLength + 3)
            {
                throw new InvalidNibusDatagram("Invalid NMS message length");
            }

            _errorCode = datagram.Data[NmsHeaderLength + 0];
            _valueType = (NmsValueType)datagram.Data[NmsHeaderLength + 1];
            _value     = ReadValue(_valueType, datagram.Data.ToArray(), NmsHeaderLength + 2);
        }
Пример #9
0
        /// <summary>
        /// Записывает тип значения и само значение в буфер.
        /// </summary>
        /// <param name="valueType">Тип значения.</param>
        /// <param name="value">Значение.</param>
        /// <returns>Массив байт максимальной длины <see cref="NmsMaxDataLength"/> с данными.</returns>
        /// <exception cref="ArgumentException">Неверный тип значения.</exception>
        /// <exception cref="FormatException">Ошибка преобразования.</exception>
        /// <exception cref="InvalidCastException">Ошибка преобразования.</exception>
        /// <exception cref="OverflowException">Ошибка преобразования.</exception>
        protected static byte[] WriteValue(NmsValueType valueType, object value)
        {
            Contract.Requires(value != null);
            Contract.Ensures(Contract.Result <byte[]>().Length <= NmsMaxDataLength);

            var data = new List <byte>(NmsMaxDataLength)
            {
                (byte)valueType
            };

            switch (valueType)
            {
            case NmsValueType.Boolean:
                data.Add(Convert.ToBoolean(value) ? (byte)1 : (byte)0);
                break;

            case NmsValueType.Int8:
                data.Add((byte)Convert.ToSByte(value));
                break;

            case NmsValueType.Int16:
                data.AddRange(BitConverter.GetBytes(Convert.ToInt16(value)));
                break;

            case NmsValueType.Int32:
                data.AddRange(BitConverter.GetBytes(Convert.ToInt32(value)));
                break;

            case NmsValueType.Int64:
                data.AddRange(BitConverter.GetBytes(Convert.ToInt64(value)));
                break;

            case NmsValueType.UInt8:
                data.Add(Convert.ToByte(value));
                break;

            case NmsValueType.UInt16:
                data.AddRange(BitConverter.GetBytes(Convert.ToUInt16(value)));
                break;

            case NmsValueType.UInt32:
                data.AddRange(BitConverter.GetBytes(Convert.ToUInt32(value)));
                break;

            case NmsValueType.UInt64:
                data.AddRange(BitConverter.GetBytes(Convert.ToUInt64(value)));
                break;

            case NmsValueType.Real32:
                data.AddRange(BitConverter.GetBytes(Convert.ToSingle(value)));
                break;

            case NmsValueType.Real64:
                data.AddRange(BitConverter.GetBytes(Convert.ToDouble(value)));
                break;

            case NmsValueType.String:
                data.AddRange(Encoding.Default.GetBytes(value.ToString()).Take(NmsMaxDataLength - 1));
                if (value.ToString().Length < NmsMaxDataLength - 1)
                {
                    data.Add(0);
                }

                break;

            case NmsValueType.DateTime:
                var dt = Convert.ToDateTime(value);
                data.AddRange(
                    new[]
                {
                    PackByte(dt.Day),
                    PackByte(dt.Month),
                    PackByte(dt.Year % 100),
                    PackByte(dt.Year / 100),
                    PackByte(dt.Hour),
                    PackByte(dt.Minute),
                    PackByte(dt.Second),
                    (byte)(dt.Millisecond / 100 & 0x0f),
                    PackByte(dt.Millisecond % 100),
                    (byte)(dt.DayOfWeek + 1)
                });
                break;
            }

            if (((byte)valueType & (byte)NmsValueType.Array) != 0)
            {
                var arrayType = (NmsValueType)((byte)valueType & ((byte)NmsValueType.Array - 1));
                foreach (var item in (IEnumerable)value)
                {
                    data.AddRange(WriteValue(arrayType, item));
                }
            }

            Contract.Assert(data.Count <= NmsMaxDataLength);
            return(data.Take(NmsMaxDataLength).ToArray());
        }
Пример #10
0
        /// <summary>
        /// Чтение значения NMS из буфера.
        /// </summary>
        /// <param name="valueType">Тип значения.</param>
        /// <param name="buffer">Буфер.</param>
        /// <param name="startIndex">Начальный индекс в буфере, с которого хранится непосредственно значение.</param>
        /// <returns>Значение NMS.</returns>
        protected static object ReadValue(NmsValueType valueType, byte[] buffer, int startIndex)
        {
            Contract.Requires(buffer != null);
            Contract.Requires(startIndex >= 0);
            switch (valueType)
            {
            case NmsValueType.Boolean:
                return(buffer[startIndex] != 0);

            case NmsValueType.Int8:
                return((sbyte)buffer[startIndex]);

            case NmsValueType.Int16:
                return(BitConverter.ToInt16(buffer, startIndex));

            case NmsValueType.Int32:
                return(BitConverter.ToInt32(buffer, startIndex));

            case NmsValueType.Int64:
                return(BitConverter.ToInt64(buffer, startIndex));

            case NmsValueType.UInt8:
                return(buffer[startIndex]);

            case NmsValueType.UInt16:
                return(BitConverter.ToUInt16(buffer, startIndex));

            case NmsValueType.UInt32:
                return(BitConverter.ToInt32(buffer, startIndex));

            case NmsValueType.UInt64:
                return(BitConverter.ToUInt64(buffer, startIndex));

            case NmsValueType.Real32:
                return(BitConverter.ToSingle(buffer, startIndex));

            case NmsValueType.Real64:
                return(BitConverter.ToDouble(buffer, startIndex));

            case NmsValueType.String:
                return(Encoding.Default.GetString(
                           buffer.Skip(startIndex).Take(NmsMaxDataLength - 1).TakeWhile(b => b != 0).ToArray()));

            case NmsValueType.DateTime:
                return(GetDateTime(buffer, startIndex));
            }

            if (((byte)valueType & (byte)NmsValueType.Array) == 0)
            {
                throw new ArgumentException("Invalid ValueType");
            }

            var arrayType   = (NmsValueType)((byte)valueType & ((byte)NmsValueType.Array - 1));
            var arraySize   = buffer.Length - startIndex /* - 1*/;
            var itemSize    = GetSizeOf(arrayType);
            var arrayLength = arraySize / itemSize;
            var array       = new object[arrayLength];

            for (var i = 0; i < arrayLength; i++)
            {
                array[i]    = ReadValue(arrayType, buffer, startIndex);
                startIndex += itemSize;
            }

            switch (arrayType)
            {
            case NmsValueType.Boolean:
                return(array.Cast <bool>().ToArray());

            case NmsValueType.Int8:
                return(array.Cast <sbyte>().ToArray());

            case NmsValueType.Int16:
                return(array.Cast <short>().ToArray());

            case NmsValueType.Int32:
                return(array.Cast <int>().ToArray());

            case NmsValueType.Int64:
                return(array.Cast <long>().ToArray());

            case NmsValueType.UInt8:
                return(array.Cast <byte>().ToArray());

            case NmsValueType.UInt16:
                return(array.Cast <ushort>().ToArray());

            case NmsValueType.UInt32:
                return(array.Cast <uint>().ToArray());

            case NmsValueType.UInt64:
                return(array.Cast <ulong>().ToArray());

            case NmsValueType.Real32:
                return(array.Cast <float>().ToArray());

            case NmsValueType.Real64:
                return(array.Cast <double>().ToArray());

            case NmsValueType.String:
                return(array.Cast <string>().ToArray());

            case NmsValueType.DateTime:
                return(array.Cast <DateTime>().ToArray());
            }
            return(array);
        }