public void Sync(IList <ObjectInfo> allObjects) { var validVarRefs = new HashSet <VariableRef>(); var tEmpty = Timestamp.Empty; foreach (ObjectInfo obj in allObjects) { if (obj.Variables == null || obj.Variables.Length == 0) { continue; } foreach (Variable v in obj.Variables) { VariableRef vref = new VariableRef(obj.ID, v.Name); validVarRefs.Add(vref); if (!map.ContainsKey(vref)) { map[vref] = new VTQ(tEmpty, Quality.Bad, v.DefaultValue); } } } foreach (var entry in map) { VariableRef vref = entry.Key; if (!validVarRefs.Contains(vref)) { validVarRefs.Remove(vref); } } this.allObjects = allObjects; }
/// <summary> /// Called by <see cref="Connection.ReadVariablesSync"/> in order to get the latest value of specific variables, /// potentially triggering time consuming downstream read requests. /// Any exception is considered an error and leads to module restart. /// </summary> /// <param name="origin">Information about the originator/initiator of this read request</param> /// <param name="variables">The variables to read</param> /// <param name="timeout">Optional timeout</param> public virtual Task <VTQ[]> ReadVariables(Origin origin, VariableRef[] variables, Duration?timeout) { var now = Timestamp.Now; var vtqs = variables.Select(v => VTQ.Make(DataValue.Empty, now, Quality.Bad)).ToArray(); return(Task.FromResult(vtqs)); }
/// <summary> /// Writes a new value to a variable waiting for the receiving module to complete the write request. /// An exception is thrown when the variable does not exist. Check the return value to verify whether /// the receiving module successfully processed the write request. /// </summary> /// <param name="objectID">The object containing the variable</param> /// <param name="variableName">The name of the variable to write</param> /// <param name="value">The new value</param> /// <param name="timeout">Optional timeout</param> public virtual async Task <Result> WriteVariableSync(ObjectRef objectID, string variableName, VTQ value, Duration?timeout = null) { WriteResult res = await WriteVariablesSync(new VariableValues { VariableValue.Make(objectID, variableName, value) }, timeout); if (res.Failed()) { return(Result.Failure(res.FailedVariables ![0].Error));
/// <summary> /// Writes a new value to a variable without waiting for the receiving module to complete the write request. /// An exception is thrown when the variable does not exist. /// </summary> /// <param name="variable">The reference to the variable to write</param> /// <param name="value">The new value</param> public virtual async Task WriteVariable(VariableRef variable, VTQ value) { await WriteVariables(new VariableValues { VariableValue.Make(variable, value) }); }
/// <summary> /// Writes a new value to a variable without waiting for the receiving module to complete the write request. /// An exception is thrown when the variable does not exist. /// </summary> /// <param name="objectID">The object containing the variable</param> /// <param name="variableName">The name of the variable to write</param> /// <param name="value">The new value</param> public virtual async Task WriteVariable(ObjectRef objectID, string variableName, VTQ value) { await WriteVariables(new VariableValues { VariableValue.Make(objectID, variableName, value) }); }
public VaribleValuePrev(VariableValue value, VTQ previousValue) { this.Value = value; this.PreviousValue = previousValue; }
private void ReadModuleVariables(XmlReader reader) { map.Clear(); if (reader.IsEmptyElement) { return; } ObjectRef currentObj = new ObjectRef(); string var_Name = ""; string var_Time = ""; string var_Quality = ""; bool inVar = false; while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: inVar = false; switch (reader.Name) { case "Obj": currentObj = ObjectRef.Make(moduleID, reader.GetAttribute("id")); break; case "Var": var_Name = reader.GetAttribute("name"); var_Time = reader.GetAttribute("time"); var_Quality = reader.GetAttribute("quality"); inVar = true; break; } break; case XmlNodeType.Text: if (inVar) { var t = TimestampFromString(var_Time); var q = QualityFromString(var_Quality); var v = DataValue.FromJSON(reader.Value); var varRef = new VariableRef(currentObj, var_Name); map[varRef] = new VTQ(t, q, v); inVar = false; } break; case XmlNodeType.EndElement: inVar = false; if (reader.Name == "Module") { return; } break; } } }
public VariableValue(VariableRef variable, VTQ value) { Variable = variable; Value = value; }
public static VariableValue Make(string moduleID, string localObjectID, string variable, VTQ value) { return(new VariableValue(VariableRef.Make(ObjectRef.Make(moduleID, localObjectID), variable), value)); }
public static VariableValue Make(ObjectRef obj, string variable, VTQ value) { return(new VariableValue(VariableRef.Make(obj, variable), value)); }
public static VariableValue Make(VariableRef varRef, VTQ value) { return(new VariableValue(varRef, value)); }
public VTQ ToVTQ() => VTQ.Make(this);
public int OnVariableValuesChanged(string moduleID, IList <VariableValuePrev> values) { var valuesToSave = new List <StoreValue>(); for (int i = 0; i < values.Count; ++i) { VariableValue value = values[i].Value; VTQ previousValue = values[i].PreviousValue; Variable?variable = fVarResolver(value.Variable); if (variable == null) { logger.Warn("OnVariableValuesChanged: invalid variable reference: " + value.Variable); continue; } Timestamp tNew = value.Value.T; Timestamp tOld = previousValue.T; History history = variable.History; if (tNew < tOld) { if (ReportTimestampWarning(history)) { logger.Warn("Timestamp of new VTQ is older than current timestamp: " + value.Variable.ToString() + "\n\tOld: " + previousValue + "\n\tNew: " + value.Value); } } else if (tNew == tOld) { if (value.Value != previousValue) { if (ReportTimestampWarning(history)) { logger.Warn("Timestamp of new VTQ is equal to current timestamp but value (or quality) differs: " + value.Variable.ToString() + "\n\tOld: " + previousValue + "\n\tNew: " + value.Value); } } } else { DataType type = variable.Type; switch (history.Mode) { case HistoryMode.None: break; case HistoryMode.Complete: valuesToSave.Add(new StoreValue(value, type)); break; case HistoryMode.ValueOrQualityChanged: { if (value.Value.V != previousValue.V || value.Value.Q != previousValue.Q) { valuesToSave.Add(new StoreValue(value, type)); } break; } case HistoryMode.Interval: { if (IsIntervalHit(tNew, history) || (tNew - tOld >= history.Interval) || IsIntervalBetweenTimetamps(tOld, tNew, history)) { valuesToSave.Add(new StoreValue(value, type)); } break; } case HistoryMode.IntervalOrChanged: { if (value.Value.V != previousValue.V || value.Value.Q != previousValue.Q || IsIntervalHit(tNew, history) || (tNew - tOld >= history.Interval) || IsIntervalBetweenTimetamps(tOld, tNew, history)) { valuesToSave.Add(new StoreValue(value, type)); } break; } case HistoryMode.IntervalExact: { if (IsIntervalHit(tNew, history)) { valuesToSave.Add(new StoreValue(value, type)); } break; } case HistoryMode.IntervalExactOrChanged: { if (value.Value.V != previousValue.V || value.Value.Q != previousValue.Q || IsIntervalHit(tNew, history)) { valuesToSave.Add(new StoreValue(value, type)); } break; } default: logger.Error("Unknown history mode: " + history.Mode); break; } } } if (valuesToSave.Count > 0) { return(SaveToDB(moduleID, valuesToSave)); } else { return(0); } }