public ObjInfo GetObjectInfo(string moduleID, IEnumerable <IModelObject> parents) => new ObjInfo( ObjectRef.Make(moduleID, GetID(parents)), GetDisplayName(parents), GetClassName(), GetChildObjectsInMember(), GetVariablesOrNull(parents), GetLocation());
private void NotifyQualityChange(List <ItemState> badItems, List <ItemState> goodItems) { if (badItems.Count == 1) { string msg = "Bad quality for reading data item: " + badItems[0].Name; var ev = AlarmOrEventInfo.Warning("Quality", msg, ObjectRef.Make(moduleID, badItems[0].ID)); notifier.Notify_AlarmOrEvent(ev); } else if (badItems.Count > 1) { string names = string.Join(", ", badItems.Select(it => it.Name)); string msg = $"Bad quality for reading {badItems.Count} data items: " + names; ObjectRef[] objs = badItems.Select(it => ObjectRef.Make(moduleID, it.ID)).ToArray(); var ev = AlarmOrEventInfo.Warning("Quality", msg, objs); notifier.Notify_AlarmOrEvent(ev); } if (goodItems.Count == 1) { string msg = "Good quality restored for data item: " + goodItems[0].Name; var ev = AlarmOrEventInfo.Info("Quality", msg, ObjectRef.Make(moduleID, goodItems[0].ID)); notifier.Notify_AlarmOrEvent(ev); } else if (goodItems.Count > 1) { string names = string.Join(", ", goodItems.Select(it => it.Name)); string msg = $"Good quality restored for {goodItems.Count} data items: " + names; ObjectRef[] objs = goodItems.Select(it => ObjectRef.Make(moduleID, it.ID)).ToArray(); var ev = AlarmOrEventInfo.Info("Quality", msg, objs); notifier.Notify_AlarmOrEvent(ev); } }
public override Task <ObjectInfo[]> GetAllObjects() { var variables = new Variable[VariablesCount]; for (int i = 0; i < VariablesCount; ++i) { variables[i] = new Variable("Variable_" + i.ToString(), DataType.Float64, DataValue.FromDouble(0), History.Complete); } var res = new ObjectInfo[] { new ObjectInfo(ObjectRef.Make(moduleID, "obj"), "Obj", "Test", null, variables) }; return(Task.FromResult(res)); }
private void Do_Notify_AlarmOrEvent(AdapterAlarmOrEvent eventInfo, Adapter adapter) { var ae = new AlarmOrEventInfo() { Time = eventInfo.Time, Severity = eventInfo.Severity, Type = eventInfo.Type, Message = adapter.Name + ": " + eventInfo.Message, Details = eventInfo.Details, AffectedObjects = eventInfo.AffectedDataItems.Select(di => ObjectRef.Make(moduleID, di)).ToArray(), Initiator = null }; notifier.Notify_AlarmOrEvent(ae); }
private void Do_Notify_AlarmOrEvent(AdapterAlarmOrEvent eventInfo, Calculation adapter) { var ae = new AlarmOrEventInfo() { Time = eventInfo.Time, Severity = eventInfo.Severity, Type = eventInfo.Type, ReturnToNormal = eventInfo.ReturnToNormal, Message = adapter.Name + ": " + eventInfo.Message, Details = eventInfo.Details, AffectedObjects = eventInfo.AffectedObjects.Select(obj => ObjectRef.Make(moduleID, obj)).ToArray(), Initiator = null }; notifier !.Notify_AlarmOrEvent(ae); }
private void Do_Notify_DataItemsChanged(DataItemValue[] result) { bool needSorting = false; for (int i = 0; i < result.Length - 1; ++i) { if (compare.Compare(result[i], result[i + 1]) > 0) { needSorting = true; break; } } if (needSorting) { Array.Sort(result, compare); } var values = new List <VariableValue>(result.Length); foreach (DataItemValue val in result) { if (dataItemsState.ContainsKey(val.ID)) { ItemState istate = dataItemsState[val.ID]; VTQ vtq = RoundFloat(istate, val.Value); istate.LastReadValue = vtq; values.Add(VariableValue.Make(ObjectRef.Make(moduleID, val.ID), VariableName, vtq)); } else { Console.Error.WriteLine($"Notify_DataItemsChanged: Unknown DataItem ID: {val.ID}"); } } if (values.Count > 0) { notifier.Notify_VariableValuesChanged(values); } }
public override async Task <ReqResult> OnUiRequestAsync(string command, DataValue parameters) { bool hasModuleID = !string.IsNullOrEmpty(configuration.ModuleID); moduleID = hasModuleID ? configuration.ModuleID : "CALC"; switch (command) { case "GetModel": { ObjectInfo root = await Connection.GetRootObject(moduleID); RootID = root.ID; await Connection.EnableVariableValueChangedEvents(SubOptions.AllUpdates(sendValueWithEvent: true), root.ID); return(await GetModelResult()); } case "Save": { SaveParams saveParams = parameters.Object <SaveParams>() ?? throw new Exception("SaveParams is null"); string objID = saveParams.ID; IDictionary <string, JToken?> dict = saveParams.Obj; MemberValue[] members = dict .Where(kv => kv.Key != "ID") .Select(entry => MakeMemberValue(objID, entry)) .ToArray(); await Connection.UpdateConfig(members); return(await GetModelResult()); } case "Delete": { ObjectRef obj = ObjectRef.Make(moduleID, parameters.GetString() ?? ""); await Connection.UpdateConfig(ObjectValue.Make(obj, DataValue.Empty)); return(await GetModelResult()); } case "AddObject": { AddObjectParams addParams = parameters.Object <AddObjectParams>() ?? throw new Exception("AddObjectParams is null"); ObjectRef objParent = ObjectRef.Make(moduleID, addParams.ParentObjID); DataValue dataValue = DataValue.FromObject(new { ID = addParams.NewObjID, Name = addParams.NewObjName }); var element = AddArrayElement.Make(objParent, addParams.ParentMember, dataValue); await Connection.UpdateConfig(element); return(await GetModelResult()); } case "MoveObject": { var move = parameters.Object <MoveObject_Params>() ?? throw new Exception("MoveObject_Params is null"); bool up = move.Up; ObjectRef obj = ObjectRef.Make(moduleID, move.ObjID); ObjectInfo objInfo = await Connection.GetObjectByID(obj); MemberRefIdx?parentMember = objInfo.Parent; if (parentMember.HasValue) { MemberValue value = await Connection.GetMemberValue(parentMember.Value.ToMemberRef()); DataValue v = value.Value; if (v.IsArray) { JArray array = (JArray)StdJson.JTokenFromString(v.JSON); int index = parentMember.Value.Index; if (up && index > 0) { JToken tmp = array[index - 1]; array[index - 1] = array[index]; array[index] = tmp; MemberValue mv = MemberValue.Make(parentMember.Value.ToMemberRef(), DataValue.FromObject(array)); await Connection.UpdateConfig(mv); } else if (!up && index < array.Count - 1) { JToken tmp = array[index + 1]; array[index + 1] = array[index]; array[index] = tmp; MemberValue mv = MemberValue.Make(parentMember.Value.ToMemberRef(), DataValue.FromObject(array)); await Connection.UpdateConfig(mv); } } } return(await GetModelResult()); } case "ReadModuleObjects": { var pars = parameters.Object <ReadModuleObjectsParams>() ?? throw new Exception("ReadModuleObjectsParams is null"); ObjectInfos objects; try { objects = await Connection.GetAllObjects(pars.ModuleID); } catch (Exception) { objects = new ObjectInfos(); } Func <Variable, bool> isMatch = GetMatchPredicate(pars.ForType); return(ReqResult.OK(new { Items = objects.Where(o => o.Variables.Any(isMatch)).Select(o => new { Type = o.ClassName, ID = o.ID.ToEncodedString(), Name = o.Name, Variables = o.Variables.Where(isMatch).Select(v => v.Name).ToArray() }).ToArray() })); } default: return(ReqResult.Bad("Unknown command: " + command)); } }
public static async Task MakeVarPubTask(MqttConfig config, ModuleInitInfo info, string certDir, Func <bool> shutdown) { var mqttOptions = MakeMqttOptions(certDir, config, "VarPub"); var varPub = config.VarPublish !; string topic = (string.IsNullOrEmpty(config.TopicRoot) ? "" : config.TopicRoot + "/") + varPub.Topic; string topicRegister = varPub.TopicRegistration.Trim() == "" ? "" : (string.IsNullOrEmpty(config.TopicRoot) ? "" : config.TopicRoot + "/") + varPub.TopicRegistration; Timestamp t = Time.GetNextNormalizedTimestamp(varPub.PublishInterval, varPub.PublishOffset); await Time.WaitUntil(t, abort : shutdown); ObjectRef objRoot = ObjectRef.Make(varPub.ModuleID, varPub.RootObject); RegCache reg = new RegCache(varPub, topicRegister); Connection clientFAST = await EnsureConnectOrThrow(info, null); IMqttClient?clientMQTT = null; while (!shutdown()) { clientFAST = await EnsureConnectOrThrow(info, clientFAST); string Now = Timestamp.Now.ToString(); VariableValues values = Filter(await clientFAST.ReadAllVariablesOfObjectTree(objRoot), varPub); clientMQTT = await EnsureConnect(mqttOptions, clientMQTT); if (clientMQTT != null) { await reg.Register(clientMQTT, values); while (values.Count > 0) { int BatchSize = Math.Min(varPub.PayloadLimit, values.Count); var batch = values.Take(BatchSize).ToArray(); values.RemoveRange(0, BatchSize); JObject[] payload = batch.Select(vv => FromVariableValue(vv, varPub)).ToArray(); var wrappedPayload = new { now = Now, tags = payload }; string msg = StdJson.ObjectToString(wrappedPayload); try { await clientMQTT.PublishAsync(topic, msg); if (varPub.PrintPayload) { Console.Out.WriteLine($"PUB: {topic}: {msg}"); } } catch (Exception exp) { Exception e = exp.GetBaseException() ?? exp; Console.Error.WriteLine($"Publish failed for topic {topic}: {e.Message}"); break; } } } t = Time.GetNextNormalizedTimestamp(varPub.PublishInterval, varPub.PublishOffset); await Time.WaitUntil(t, abort : shutdown); } await clientFAST.Close(); Close(clientMQTT); }
public override async Task <ReqResult> OnUiRequestAsync(string command, DataValue parameters) { bool hasModuleID = !(configuration == null || string.IsNullOrEmpty(configuration.ModuleID)); string moduleID = hasModuleID ? configuration !.ModuleID : "IO"; switch (command) { case "GetModel": { objects = await Connection.GetAllObjects(moduleID); mapVariables.Clear(); ObjectInfo root = objects.FirstOrDefault(o => !o.Parent.HasValue); List <VariableValue> variables = await Connection.ReadAllVariablesOfObjectTree(root.ID); await Connection.EnableVariableValueChangedEvents(SubOptions.AllUpdates(sendValueWithEvent: true), root.ID); foreach (VariableValue vv in variables) { mapVariables[vv.Variable] = vv.Value; } TreeNode node = TransformModel(objects); MetaInfos types = await Connection.GetMetaInfos(moduleID); objTypes.Clear(); foreach (ClassInfo ci in types.Classes) { objTypes[ci.FullName] = ci; } enumTypes.Clear(); foreach (EnumInfo en in types.Enums) { enumTypes[en.FullName] = en; } structTypes.Clear(); foreach (StructInfo sn in types.Structs) { structTypes[sn.FullName] = sn; } JObject typMap = new JObject(); foreach (ClassInfo ci in types.Classes) { var members = ci.ObjectMember .Where(m => m.Dimension == Dimension.Array) .Select(m => new { Array = m.Name, Type = m.ClassName }).ToArray(); var entry = new { ObjectMembers = members }; typMap[ci.FullName] = new JRaw(StdJson.ObjectToString(entry)); } var locations = await Connection.GetLocations(); hasLocations = locations.Count > 0; rootLocation = hasLocations ? LocationRef.FromLocationID(locations[0].ID) : (LocationRef?)null; return(ReqResult.OK(new { ObjectTree = node, TypeInfo = typMap, Locations = locations, })); } case "GetObject": { GetObjectParams pars = parameters.Object <GetObjectParams>() ?? throw new Exception("GetObjectParams is null"); var values = await GetObjectMembers(pars.ID, pars.Type); ClassInfo info = objTypes[pars.Type]; var childTypes = info.ObjectMember .GroupBy(om => om.ClassName) .Select(g => new ChildType() { TypeName = g.Key, Members = g.Select(x => x.Name).ToArray() }).ToList(); var res = new { ObjectValues = values, ChildTypes = childTypes }; return(ReqResult.OK(res)); } case "Save": { SaveParams saveParams = parameters.Object <SaveParams>() ?? throw new Exception("SaveParams is null"); foreach (var m in saveParams.Members) { Console.WriteLine(m.Name + " => " + m.Value); } ObjectRef obj = ObjectRef.FromEncodedString(saveParams.ID); MemberValue[] mw = saveParams.Members.Select(m => MemberValue.Make(obj, m.Name, DataValue.FromJSON(m.Value))).ToArray(); await Connection.UpdateConfig(mw); objects = await Connection.GetAllObjects(moduleID); TreeNode node = TransformModel(objects); var values = await GetObjectMembers(saveParams.ID, saveParams.Type); return(ReqResult.OK(new { ObjectValues = values, ObjectTree = node })); } case "Delete": { ObjectRef obj = ObjectRef.FromEncodedString(parameters.GetString() ?? ""); await Connection.UpdateConfig(ObjectValue.Make(obj, DataValue.Empty)); objects = await Connection.GetAllObjects(moduleID); TreeNode node = TransformModel(objects); return(ReqResult.OK(node)); } case "AddObject": { AddObjectParams addParams = parameters.Object <AddObjectParams>() ?? throw new Exception("AddObjectParams is null"); ObjectRef objParent = ObjectRef.FromEncodedString(addParams.ParentObjID); DataValue dataValue = DataValue.FromObject(new { ID = addParams.NewObjID, Name = addParams.NewObjName }); var element = AddArrayElement.Make(objParent, addParams.ParentMember, dataValue); await Connection.UpdateConfig(element); objects = await Connection.GetAllObjects(moduleID); List <VariableValue> newVarVals = await Connection.ReadAllVariablesOfObjectTree(ObjectRef.Make(objParent.ModuleID, addParams.NewObjID)); foreach (VariableValue vv in newVarVals) { mapVariables[vv.Variable] = vv.Value; } TreeNode node = TransformModel(objects); return(ReqResult.OK(new { ObjectID = ObjectRef.Make(moduleID, addParams.NewObjID), Tree = node })); } case "DragDrop": { DragDropParams dropParams = parameters.Object <DragDropParams>() ?? throw new Exception("DragDropParams is null"); ObjectRef obj = ObjectRef.FromEncodedString(dropParams.FromID); ObjectValue objValue = await Connection.GetObjectValueByID(obj); var deleteObj = ObjectValue.Make(obj, DataValue.Empty); ObjectRef objParent = ObjectRef.FromEncodedString(dropParams.ToID); var addElement = AddArrayElement.Make(objParent, dropParams.ToArray, objValue.Value); await Connection.UpdateConfig(new ObjectValue[] { deleteObj }, new MemberValue[0], new AddArrayElement[] { addElement }); objects = await Connection.GetAllObjects(moduleID); TreeNode node = TransformModel(objects); return(ReqResult.OK(node)); } case "WriteVariable": { var write = parameters.Object <WriteVariable_Params>() ?? throw new Exception("WriteVariable_Params is null"); VTQ vtq = new VTQ(Timestamp.Now, Quality.Good, DataValue.FromJSON(write.V)); await Connection.WriteVariable(ObjectRef.FromEncodedString(write.ObjID), write.Var, vtq); return(ReqResult.OK()); } case "MoveObject": { var move = parameters.Object <MoveObject_Params>() ?? throw new Exception("MoveObject_Params is null"); bool up = move.Up; ObjectRef obj = ObjectRef.FromEncodedString(move.ObjID); ObjectInfo objInfo = await Connection.GetObjectByID(obj); MemberRefIdx?parentMember = objInfo.Parent; if (parentMember.HasValue) { MemberValue value = await Connection.GetMemberValue(parentMember.Value.ToMemberRef()); DataValue v = value.Value; if (v.IsArray) { JArray array = (JArray)StdJson.JTokenFromString(v.JSON); int index = parentMember.Value.Index; if (up && index > 0) { JToken tmp = array[index - 1]; array[index - 1] = array[index]; array[index] = tmp; MemberValue mv = MemberValue.Make(parentMember.Value.ToMemberRef(), DataValue.FromObject(array)); await Connection.UpdateConfig(mv); } else if (!up && index < array.Count - 1) { JToken tmp = array[index + 1]; array[index + 1] = array[index]; array[index] = tmp; MemberValue mv = MemberValue.Make(parentMember.Value.ToMemberRef(), DataValue.FromObject(array)); await Connection.UpdateConfig(mv); } } } objects = await Connection.GetAllObjects(moduleID); TreeNode node = TransformModel(objects); return(ReqResult.OK(node)); } case "Browse": { var browse = parameters.Object <Browse_Params>() ?? throw new Exception("Browse_Params is null"); var m = MemberRef.Make(ObjectRef.FromEncodedString(browse.ObjID), browse.Member); BrowseResult res = await Connection.BrowseObjectMemberValues(m); return(ReqResult.OK(res.Values.Select(d => d.GetString()))); } case "GetNewID": { string type = parameters.GetString() ?? throw new Exception("Type parameter is null"); string id = GetObjectID(type); return(ReqResult.OK(id)); } default: return(ReqResult.Bad("Unknown command: " + command)); } }
private static WriteResult MapWriteResults(string moduleID, IEnumerable <WriteDataItemsResult> list) { if (list.All(r => r.IsOK())) { return(WriteResult.OK); } VariableError[] failures = list .Where(r => r.Failed()) .SelectMany(x => x.FailedDataItems.Select(di => new VariableError(ObjectRef.Make(moduleID, di.ID), VariableName, di.Error))) .ToArray(); return(WriteResult.Failure(failures)); }