Esempio n. 1
0
        private static DataValue ConfigToIndentedDataValue(ViewConfig configuration)
        {
            string json = StdJson.ObjectToString(configuration, indented: true);
            string c    = "\r\n" + Indent(json, 8) + "\r\n      ";

            return(DataValue.FromJSON(c));
        }
Esempio n. 2
0
        private async Task <VTQ> ReadDataItemFromDB(string itemID, string query, VTQ lastValue)
        {
            var rows = new List <JObject>();

            using (DbCommand cmd = CreateCommand(dbConnection !, query)) {
                using (var reader = await cmd.ExecuteReaderAsync()) {
                    while (reader.Read())
                    {
                        int     n      = reader.FieldCount;
                        JObject objRow = new JObject();

                        for (int i = 0; i < n; ++i)
                        {
                            string name  = reader.GetName(i);
                            object value = reader.GetValue(i);
                            objRow[name] = JToken.FromObject(value);
                        }

                        rows.Add(objRow);
                    }
                }
            }

            DataValue dataValue = DataValue.FromObject(rows, indented: true);

            if (lastValue.V == dataValue)
            {
                return(lastValue);
            }

            VTQ vtq = VTQ.Make(dataValue, Timestamp.Now.TruncateMilliseconds(), Quality.Good);

            int    N        = rows.Count;
            string firstRow = N == 0 ? "" : StdJson.ObjectToString(rows[0], indented: false);

            if (N == 0)
            {
                PrintLine($"Read 0 rows for {itemID}");
            }
            else if (N == 1)
            {
                PrintLine($"Read 1 row for {itemID}: {firstRow}");
            }
            else
            {
                PrintLine($"Read {N} rows for {itemID}. First row: {firstRow}");
            }

            return(vtq);
        }
Esempio n. 3
0
        protected virtual string SerializeModelToString(T model)
        {
            switch (modelFormat)
            {
            case ModelFormat.XML:
                return(Xml.ToXml(model));

            case ModelFormat.JSON:
                return(StdJson.ObjectToString(model, indented: true));

            default:
                throw new Exception($"Model format {modelFormat} not implemented in SerializeModelToString");
            }
        }
Esempio n. 4
0
        private async Task <List <ObjectMember> > GetObjectMembers(string id, string type)
        {
            ObjectRef obj  = ObjectRef.FromEncodedString(id);
            ClassInfo info = objTypes[type];

            MemberRef[]   members   = info.SimpleMember.Select(m => MemberRef.Make(obj, m.Name)).ToArray();
            MemberValue[] memValues = await Connection.GetMemberValues(members);

            var values = new List <ObjectMember>();

            for (int i = 0; i < info.SimpleMember.Count; ++i)
            {
                SimpleMember m            = info.SimpleMember[i];
                MemberValue  v            = memValues[i];
                string       defaultValue = "";
                if (m.DefaultValue.HasValue && m.Dimension != Dimension.Array)
                {
                    defaultValue = m.DefaultValue.Value.JSON;
                }
                else if (m.Type == DataType.Struct)
                {
                    defaultValue = StdJson.ObjectToString(GetStructDefaultValue(m), indented: true, ignoreNullValues: false);
                    //Console.WriteLine("=> " + m.Name + ": " + defaultValue);
                }
                else
                {
                    defaultValue = DataValue.FromDataType(m.Type, 1).JSON;
                }
                var member = new ObjectMember()
                {
                    Key           = obj.ToEncodedString() + "__" + m.Name,
                    Name          = m.Name,
                    Type          = m.Type.ToString(),
                    IsScalar      = m.Dimension == Dimension.Scalar,
                    IsOption      = m.Dimension == Dimension.Optional,
                    IsArray       = m.Dimension == Dimension.Array,
                    Category      = m.Category,
                    Browseable    = m.Browseable,
                    Value         = new JRaw(v.Value.JSON),
                    ValueOriginal = new JRaw(v.Value.JSON),
                    EnumValues    = ResolveEnum(m),
                    StructMembers = ResolveStruct(m),
                    DefaultValue  = defaultValue
                };
                values.Add(member);
            }
            return(values);
        }
Esempio n. 5
0
            public async Task Register(IMqttClient clientMQTT, VariableValues allValues)
            {
                if (topic == "")
                {
                    return;
                }

                var newVarVals = allValues.Where(v => !registeredVars.Contains(v.Variable)).ToList();

                while (newVarVals.Count > 0)
                {
                    int BatchSize = Math.Min(varPub.PayloadLimit, newVarVals.Count);
                    var batch     = newVarVals.Take(BatchSize).ToArray();
                    newVarVals.RemoveRange(0, BatchSize);

                    JObject[] payload = batch.Select(vv => FromVariableValue(vv, varPub)).ToArray();

                    string msg = StdJson.ObjectToString(payload);

                    try {
                        await clientMQTT.PublishAsync(topic, msg);

                        foreach (var vv in batch)
                        {
                            registeredVars.Add(vv.Variable);
                        }

                        if (varPub.PrintPayload)
                        {
                            Console.Out.WriteLine($"REG PUB: {topic}: {msg}");
                        }
                    }
                    catch (Exception exp) {
                        Exception e = exp.GetBaseException() ?? exp;
                        Console.Error.WriteLine($"Reg Publish failed for topic {topic}: {e.Message}");
                        break;
                    }
                }
            }
Esempio n. 6
0
        private async Task <ReqResult> HandlePost(HttpRequest request, HttpResponse response)
        {
            string path = request.Path;

            try {
                if (path == Path_Login)
                {
                    string?user;
                    string?pass;
                    using (var reader = new StreamReader(request.Body, Encoding.UTF8)) {
                        var obj = await StdJson.JObjectFromReaderAsync(reader);

                        user = (string?)obj["user"];
                        pass = (string?)obj["pass"];
                        if (user == null || pass == null)
                        {
                            return(ReqResult.Bad("Missing user and password."));
                        }
                    }

                    var        session = new Session();
                    Connection connection;
                    try {
                        connection = await HttpConnection.ConnectWithUserLogin("localhost", clientPort, user, pass, null, session, timeoutSeconds : 90);
                    }
                    catch (Exception exp) {
                        logWarn(exp.Message);
                        return(ReqResult.Bad(exp.Message));
                    }
                    await session.SetConnection(connection, model, moduleID, viewTypes);

                    sessions[session.ID] = session;

                    var result = new JObject();
                    result["sessionID"] = session.ID;
                    string str = StdJson.ObjectToString(uiModel);
                    JRaw   raw = new JRaw(str);
                    result["model"] = raw;
                    return(ReqResult.OK(result));
                }
                else if (path.StartsWith(Path_ViewReq))
                {
                    string viewRequest = path.Substring(Path_ViewReq.Length);

                    (Session session, string viewID) = GetSessionFromQuery(request.QueryString.ToString());

                    string content;
                    using (var reader = new StreamReader(request.Body, Encoding.UTF8)) {
                        content = await reader.ReadToEndAsync();
                    }
                    return(await session.OnViewCommand(viewID, viewRequest, DataValue.FromJSON(content)));
                }
                else if (path == Path_ActivateView)
                {
                    (Session session, string viewID) = GetSessionFromQuery(request.QueryString.ToString());
                    await session.OnActivateView(viewID);

                    return(ReqResult.OK());
                }
                else if (path == Path_DuplicateView)
                {
                    (Session session, string viewID) = GetSessionFromQuery(request.QueryString.ToString());
                    string newViewID = await session.OnDuplicateView(viewID);

                    uiModel = MakeUiModel(model, viewTypes);

                    return(ReqResult.OK(new {
                        newViewID,
                        model = uiModel
                    }));
                }
                else if (path == Path_DuplicateConvertView)
                {
                    (Session session, string viewID) = GetSessionFromQuery(request.QueryString.ToString());
                    string newViewID = await session.OnDuplicateConvertHistoryPlot(viewID);

                    uiModel = MakeUiModel(model, viewTypes);

                    return(ReqResult.OK(new {
                        newViewID,
                        model = uiModel
                    }));
                }
                else if (path == Path_RenameView)
                {
                    (Session session, string viewID) = GetSessionFromQuery(request.QueryString.ToString());

                    string?newViewName;
                    using (var reader = new StreamReader(request.Body, Encoding.UTF8)) {
                        var obj = await StdJson.JObjectFromReaderAsync(reader);

                        newViewName = (string?)obj["newViewName"];
                        if (newViewName == null)
                        {
                            return(ReqResult.Bad("Missing newViewName"));
                        }
                    }

                    await session.OnRenameView(viewID, newViewName);

                    uiModel = MakeUiModel(model, viewTypes);

                    return(ReqResult.OK(new {
                        model = uiModel
                    }));
                }
                else if (path == Path_MoveView)
                {
                    (Session session, string viewID) = GetSessionFromQuery(request.QueryString.ToString());

                    bool up = false;
                    using (var reader = new StreamReader(request.Body, Encoding.UTF8)) {
                        var obj = await StdJson.JObjectFromReaderAsync(reader);

                        up = (bool)obj["up"] !;
                    }

                    await session.OnMoveView(viewID, up);

                    uiModel = MakeUiModel(model, viewTypes);

                    return(ReqResult.OK(new {
                        model = uiModel
                    }));
                }
                else if (path == Path_DeleteView)
                {
                    (Session session, string viewID) = GetSessionFromQuery(request.QueryString.ToString());
                    await session.OnDeleteView(viewID);

                    uiModel = MakeUiModel(model, viewTypes);

                    return(ReqResult.OK(new {
                        model = uiModel
                    }));
                }
                else if (path == Path_Logout)
                {
                    string sessionID;
                    using (var reader = new StreamReader(request.Body, Encoding.UTF8)) {
                        sessionID = await reader.ReadToEndAsync();
                    }

                    if (sessions.ContainsKey(sessionID))
                    {
                        Session session = sessions[sessionID];
                        var     ignored = session.Close();
                        sessions.Remove(sessionID);
                    }

                    return(ReqResult.OK());
                }
                else
                {
                    return(ReqResult.Bad("Invalid path: " + path));
                }
            }
            catch (InvalidSessionException exp) {
                logWarn("HandlePost: " + exp.Message);
                return(ReqResult.Bad(exp.Message));
            }
            catch (Exception exp) {
                logWarn("HandlePost:", exp);
                return(ReqResult.Bad(exp.Message));
            }
        }
Esempio n. 7
0
        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));
            }
        }