Esempio n. 1
0
        private async Task PerformWriteAsync(ICollection <IPlcItem> plcItems, CancellationToken cancellationToken)
        {
            const PlcItemUsageType usageType = PlcItemUsageType.Write;
            var underlyingPlc = AgLinkPlc.VerifyConnectivity(this, plcItems, usageType);

            // Create the mapping.
            var(mapping, allAgLinkItems) = AgLinkPlc.CreateMappingAndAgLinkItems(plcItems, usageType);

            // Write to the plc.
            var writeResult = await Task.Run(() => underlyingPlc.WriteMixEx(allAgLinkItems, allAgLinkItems.Length), cancellationToken);

            // Verify the total result.
            //! Ignore the total result and inspect the result of each item individually.
            var result = AgLinkPlc.ConvertToAgLinkResult(writeResult);

            //if (result != AgLinkResult.Success)
            //{
            //	var errorMessage = AgLinkPlc.ErrorMapping.GetErrorMessageForCode(writeResult);
            //	var items = plcItems.Select(item => (item, "General writing error.")).ToArray();
            //	throw new WritePlcException(new IPlcItem[0], items, $"Could not write any items to {this:LOG}. AGLink returned error code '{result}' ({errorMessage}).");
            //}

            // Verify the result of all items.
            var(validItems, failedItems) = AgLinkPlc.VerifyPlcItemResults(mapping, allAgLinkItems, false);
            if (failedItems.Any())
            {
                throw new WritePlcException(validItems, failedItems, $"Some of the items couldn't be written. See the '{nameof(ReadOrWritePlcException.FailedItems)}' property for further information.");
            }
        }
Esempio n. 2
0
        private static (ICollection <IPlcItem> ValidItems, ICollection <(IPlcItem FailedItem, string ErrorMessage)>) VerifyPlcItemResults(ICollection <ReadPlcItemWrapper> mapping, ICollection <AGL4.DATA_RW40> allAgLinkItems, bool transferData)
        {
            var validItems  = new List <IPlcItem>(mapping.Count);
            var failedItems = new List <(IPlcItem FailedItem, string ErrorMessage)>(0);            //! Assume that no errors occur to save memory.

            // Iterate each plc item and get the data for all AGLink items that where needed to handle it.
            foreach (var(plcItem, start, amount) in mapping)
            {
                // Get all ag link items of this plc item.
                var agLinkItems = allAgLinkItems.Skip(start).Take(amount).ToArray();

                // Check if any of those have failed.
                var itemResult = agLinkItems
                                 .Select(agLinkItem => agLinkItem.Result)
                                 .FirstOrDefault(resultCode => resultCode != 0)
                ;

                var result = AgLinkPlc.ConvertToAgLinkResult(itemResult);
                if (result != AgLinkResult.Success)
                {
                    failedItems.Add((plcItem, AgLinkPlc.ErrorMapping.GetErrorMessageForCode(itemResult)));
                }
                else
                {
                    validItems.Add(plcItem);
                    if (transferData)
                    {
                        var data = agLinkItems.SelectMany(agLinkItem => agLinkItem.B).ToArray();
                        AgLinkPlc.TransferValue(plcItem, data);
                    }
                }
            }

            return(validItems, failedItems);
        }
Esempio n. 3
0
        private async Task PerformReadAsync(ICollection <IPlcItem> plcItems, CancellationToken cancellationToken)
        {
            const PlcItemUsageType usageType = PlcItemUsageType.Read;
            var underlyingPlc = AgLinkPlc.VerifyConnectivity(this, plcItems, usageType);

            // Create the mapping.
            var(mapping, allAgLinkItems) = AgLinkPlc.CreateMappingAndAgLinkItems(plcItems, usageType);

            // Read from the plc.
            //! The return value may be zero even if some or all of the items failed. To get the real result the 'Result' property of the AGLink item (AGL4.DATA_RW40.Result) must be checked.
            var readResult = await Task.Run(() => underlyingPlc.ReadMixEx(allAgLinkItems, allAgLinkItems.Length), cancellationToken);

            // Verify the total result.
            //! Ignore the total result and inspect the result of each item individually.
            var result = AgLinkPlc.ConvertToAgLinkResult(readResult);

            //if (result != AgLinkResult.Success)
            //{
            //	var errorMessage = AgLinkPlc.ErrorMapping.GetErrorMessageForCode(readResult);
            //	var items = plcItems.Select(item => (item, "General reading error.")).ToArray();
            //	throw new ReadPlcException(new IPlcItem[0], items, $"Could not read any items from {this:LOG}. AGLink returned error code '{result}' ({errorMessage}).");
            //}

            // Verify the result of all items and transfer the value.
            var(validItems, failedItems) = AgLinkPlc.VerifyPlcItemResults(mapping, allAgLinkItems, true);
            if (failedItems.Any())
            {
                throw new ReadPlcException(validItems, failedItems, $"Some of the items couldn't be read. See the '{nameof(ReadOrWritePlcException.FailedItems)}' property for further information.");
            }
        }