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())); } }