Example #1
0
        public override async Task <WriteResult> WriteVariables(Origin origin, VariableValue[] values, Duration?timeout)
        {
            var failed        = new List <VariableError>(0);
            var skippedItems  = new List <string>(0);
            var adapter2Items = new Dictionary <AdapterState, List <DataItemValue> >();

            foreach (VariableValue vv in values)
            {
                string id = vv.Variable.Object.LocalObjectID;

                if (vv.Variable.Name != VariableName)
                {
                    Log_Warn("InvalidVarNames", "WriteVariables: Invalid variable name: " + vv.Variable, origin);
                    failed.Add(new VariableError(vv.Variable, "Invalid variable name"));
                    continue;
                }

                if (!dataItemsState.ContainsKey(id))
                {
                    Log_Warn("UnknownID", "WriteVariables: No writable data item found with id: " + id, origin);
                    failed.Add(new VariableError(vv.Variable, "No writable data item found with id " + id));
                    continue;
                }

                ItemState itemState = dataItemsState[id];

                if (!itemState.Writeable)
                {
                    Log_Warn("NotWriteable", $"WriteVariables: Data item {id} is not writable", origin);
                    failed.Add(new VariableError(vv.Variable, $"Data item {id} is not writable"));
                    continue;
                }

                AdapterState adapter = itemState.Adapter;
                if (adapter.SetOfPendingWriteItems.Contains(id))
                {
                    skippedItems.Add(id);
                    failed.Add(new VariableError(vv.Variable, "Previous write still pending"));
                    continue;
                }

                if (!adapter2Items.ContainsKey(adapter))
                {
                    adapter2Items[adapter] = new List <DataItemValue>();
                }
                adapter2Items[adapter].Add(new DataItemValue(id, vv.Value));
                adapter.SetOfPendingWriteItems.Add(id);
            }

            if (skippedItems.Count > 0)
            {
                string warn = string.Format("Write of {0} data items skipped because of pending write: {1}", skippedItems.Count, string.Join(", ", skippedItems));
                Log_Warn("WritesPending", warn, origin);
            }

            var allWriteTasks = new List <Task <WriteDataItemsResult> >(adapter2Items.Count);

            foreach (var adapterItems in adapter2Items)
            {
                AdapterState         adapter = adapterItems.Key;
                List <DataItemValue> items   = adapterItems.Value;

                Task <WriteDataItemsResult> task = AdapterWriteTask(adapter, items, timeout);
                allWriteTasks.Add(task);
            }

            WriteDataItemsResult[] resArr = await Task.WhenAll(allWriteTasks);

            WriteResult res = MapWriteResults(moduleID, resArr);

            if (res.Failed())
            {
                failed.AddRange(res.FailedVariables);
            }

            if (failed.Count == 0)
            {
                return(WriteResult.OK);
            }
            else
            {
                return(WriteResult.Failure(failed.ToArray()));
            }
        }