Ejemplo n.º 1
0
 public Execution(PlcRawData plcRawData, Dictionary <string, PlcObjectBinding> bindings, int validationTimeMS)
 {
     ValidationTimeMs = validationTimeMS;
     PlcRawData       = plcRawData;
     Bindings         = bindings;
     Partitions       = plcRawData.GetPartitonsByOffset(bindings.Values.Select(x => new Tuple <int, int>(x.Offset, x.Size)));
 }
Ejemplo n.º 2
0
 public PlcObjectBinding(PlcRawData rawData, PlcObject metaData, int offset, int validationTimeMs, bool fullType = false)
 {
     RawData            = rawData;
     MetaData           = metaData;
     Offset             = offset;
     ValidationTimeInMs = validationTimeMs;
     FullType           = fullType;
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Create RawReadOperations to use it in the reader. This method tries to optimize the PLC access,
        /// to it creates blocks for minimum operations on plc.
        /// </summary>
        public IEnumerable <PlcRawData> CreateRawReadOperations(string selector, IEnumerable <KeyValuePair <string, Tuple <int, PlcObject> > > objects, int readDataBlockSize)
        {
            var        rawBlocks = new List <PlcRawData>();
            PlcRawData pred      = null;
            var        offsetCountedAsBoolean = -1;
            var        offset = 0;

            foreach (var item in objects.OrderBy(i => i.Value.Item1 + i.Value.Item2.Offset.Bytes)
                     .ThenBy(i => i.Value.Item2.Offset.Bits)
                     .ThenBy(i => i.Key.Length))
            {
                var count         = true;
                var currentOffset = item.Value.Item1 + item.Value.Item2.Offset.Bytes;
                var sizeInBytes   = item.Value.Item2.Size.Bytes;

                if (item.Value.Item2 is PlcBool)
                {
                    if (currentOffset != offsetCountedAsBoolean)
                    {
                        offsetCountedAsBoolean = currentOffset;
                    }
                    else
                    {
                        count = false;
                    }
                }

                var current = new PlcRawData(readDataBlockSize)
                {
                    Offset   = currentOffset,
                    Size     = sizeInBytes == 0 && count ? 1 : sizeInBytes,
                    Selector = selector
                };


                if (pred == null)
                {
                    rawBlocks.Add(current);
                    pred   = current;
                    offset = 0;
                }
                else
                {
                    var directOffset = pred.Offset + pred.Size;
                    if (directOffset == current.Offset)
                    {
                        //follows direct
                        offset     = current.Offset - pred.Offset;
                        pred.Size += current.Size;
                    }
                    else if (directOffset > current.Offset)
                    {
                        //is subElement
                        offset = current.Offset - pred.Offset;
                        var freeBytesInParent = pred.Size - offset;
                        if (current.Size > freeBytesInParent)
                        {
                            //Update size if we have an overlapping item
                            pred.Size += (current.Size - freeBytesInParent);
                        }
                    }
                    else
                    {
                        var unusedBytes  = current.Offset - directOffset;
                        var modifiedSize = pred.Size + unusedBytes + current.Size;
                        if (pred.Size + unusedBytes + current.Size <= readDataBlockSize)
                        {
                            //It is OK to use one block, because its in one PDU. Better one read than many
                            if (count)
                            {
                                offset    = pred.Size + unusedBytes;
                                pred.Size = modifiedSize;
                            }
                        }
                        else
                        {
                            rawBlocks.Add(current);
                            pred   = current;
                            offset = 0;
                        }
                    }
                }


                pred.AddReference(item.Key, offset, item.Value.Item2);


                if (item.Value.Item2 is PlcArray array)
                {
                    HandleArray(offset, array, item, pred);
                }
            }

            return(rawBlocks);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Create Raw Read operations for Array Elements
        /// </summary>
        private void HandleArray(int offset, PlcArray array, KeyValuePair <string, Tuple <int, PlcObject> > item, PlcRawData pred, string dimension = "")
        {
            var arrayOffset = offset;

            for (var i = array.From; i <= array.To; i++)
            {
                var index   = $"[{i}]";
                var element = array.ArrayType is PlcStruct
                    ? new PlcObjectRef(index, array.ArrayType)
                    : PlcObjectFactory.CreatePlcObjectForArrayIndex(array.ArrayType, i, array.From);

                var name     = $"{item.Key}{index}";
                var elemName = string.IsNullOrWhiteSpace(dimension) ? name :  $"{dimension}{index}";
                if (element is PlcArray)
                {
                    pred.AddReference(elemName, arrayOffset, element);
                    HandleArray(arrayOffset, element as PlcArray, item, pred, name);
                    arrayOffset += array.ArrayType.Size.Bytes;
                }
                else
                {
                    pred.AddReference(elemName, arrayOffset, element);
                    arrayOffset += array.ArrayType.Size.Bytes;
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Create Raw Read operations for Array Elements
        /// </summary>
        private void HandleArray(int offset, PlcArray array, KeyValuePair <string, Tuple <int, PlcObject> > item, PlcRawData pred, string dimension = "")
        {
            var arrayOffset = offset;

            for (var i = array.From; i <= array.To; i++)
            {
                var element = array.ArrayType is PlcStruct
                    ? new PlcObjectRef(string.Format("[{0}]", i), array.ArrayType)
                    : PlcObjectFactory.CreatePlcObjectForArrayIndex(array.ArrayType, i, array.From);

                if (element is PlcArray)
                {
                    var elemName = string.IsNullOrWhiteSpace(dimension) ? string.Format("{0}[{1}]", item.Key, i) : dimension + string.Format("[{0}]", i);
                    pred.AddReference(elemName, arrayOffset, element);
                    HandleArray(arrayOffset, element as PlcArray, item, pred, string.Format("{0}[{1}]", item.Key, i));
                    arrayOffset += array.ArrayType.Size.Bytes;
                }
                else
                {
                    var elemName = string.IsNullOrWhiteSpace(dimension) ? string.Format("{0}[{1}]", item.Key, i) : dimension + string.Format("[{0}]", i);
                    pred.AddReference(elemName, arrayOffset, element);
                    arrayOffset += array.ArrayType.Size.Bytes;
                }
            }
        }