private static IServiceCollection AddCdePubSubServices(this IServiceCollection collection)
        {
            collection.AddSingleton(sp =>
            {
                sp.UseCde();
                var engines = TheThingRegistry.GetBaseEngines(false);
                var engine  = engines.FirstOrDefault(e => e.GetEngineName() == InfrastructureEngine);
                if (engine != null)
                {
                    return(engine.GetBaseThing());
                }

                if (!TheCDEngines.RegisterNewMiniRelay(InfrastructureEngine))
                {
                    throw new InvalidOperationException("Failed to register CDE infrastructure engine");
                }

                engine = TheThingRegistry.GetBaseEngine(InfrastructureEngine, false);
                return(engine.GetBaseThing());
            });

            collection.AddSingleton(sp => new Publisher(Operator.GetLine(sp.GetRequiredService <TheThing>())).ConnectAsync().Result as Publisher)
            .AddSingleton(sp => sp.GetRequiredService <Publisher>() as IPublisher);
            collection.AddSingleton(sp => new Subscriber(Operator.GetLine(sp.GetRequiredService <TheThing>()), sp.GetRequiredService <Publisher>()))
            .AddSingleton(sp => sp.GetRequiredService <Subscriber>() as ISubscriber);

            return(collection);
        }
Example #2
0
        public MainWindow()
        {
            InitializeComponent();

            // Start the CDEngine communication channels
            StartCDEngineHost();

            TheBaseEngine.WaitForEnginesStartedAsync().ContinueWith(t =>
            {
                try
                {
                    // Express our interest in the EngineName used for the chat, so that a subscription to the cloud is established even though the engine has not matching plug-in on this node
                    TheCDEngines.RegisterNewMiniRelay(strChatEngine);

                    // Intercept any messages sent to the chat engine
                    var chatEngine = TheThingRegistry.GetBaseEngine(strChatEngine);
                    chatEngine.RegisterEvent(eEngineEvents.IncomingMessage, HandleMessage);

                    // Intercept any messages sent to the ContentService (we will use that as the originating thing, and acknowledge messages will come back to it)
                    TheThingRegistry.GetBaseEngineAsThing(eEngineName.ThingService).RegisterEvent(eThingEvents.IncomingMessage, HandleMessage);
                }
                catch
                {
                }
            });
        }
Example #3
0
        public override bool Init()
        {
            if (!mIsInitStarted)
            {
                mIsInitStarted = true;
                MyBaseEngine.RegisterEvent(eEngineEvents.ShutdownEvent, OnShutdown);
                TheThing.SetSafePropertyBool(MyBaseThing, "IsConnected", false);

                IBaseEngine tBase = TheThingRegistry.GetBaseEngine(TheThing.GetSafePropertyString(MyBaseThing, "ISOLaterName"), true);
                if (tBase != null)
                {
                    MyIsolator = tBase.GetISOLater() as Process;
                    if (MyIsolator == null)
                    {
                        MyBaseThing.LastMessage = "Engine not isolated";
                        MyBaseThing.StatusLevel = 3;
                        mIsInitCompleted        = true;
                        return(true);
                    }
                    MyBaseThing.LastMessage = "KPIs monitor ready";
                    MyBaseThing.StatusLevel = 1;
                    if (TheThing.GetSafePropertyBool(MyBaseThing, "AutoConnect"))
                    {
                        Connect();
                    }
                }
                else
                {
                    MyBaseThing.LastMessage = "Base Engine cloud not be located";
                    MyBaseThing.StatusLevel = 3;
                }
                mIsInitCompleted = true;
            }
            return(true);
        }
        void sinkRegisterIsos()
        {
            var tEngs = TheThingRegistry.GetBaseEnginesAsThing(false, true);

            foreach (var t in tEngs)
            {
                if (TheThing.GetSafePropertyBool(t, "IsIsolated"))
                {
                    IBaseEngine tBase = TheThingRegistry.GetBaseEngine(t, true);
                    if (tBase != null && tBase.GetISOLater() != null)
                    {
                        TheThing tT   = TheThingRegistry.GetThingByFunc(MyBaseEngine.GetEngineName(), s => s.DeviceType == TheISOlaterKPIs.eDeviceType && TheThing.GetSafePropertyString(s, "ISOLaterName") == t.EngineName);
                        var      tKPI = new TheISOlaterKPIs(tT, this, t.EngineName);
                        TheThingRegistry.RegisterThing(tKPI);
                    }
                }
            }
            List <TheThing> tDevList = TheThingRegistry.GetThingsByProperty(MyBaseEngine.GetEngineName(), Guid.Empty, "DeviceType", TheKPIReport.eDeviceType);

            if (tDevList.Count > 0)
            {
                foreach (TheThing tDev in tDevList)
                {
                    if (tDev.GetObject() == null)
                    {
                        TheKPIReport cs = new TheKPIReport(tDev, this);
                        TheThingRegistry.RegisterThing(cs);
                    }
                }
            }
        }
 public IBaseEngine GetBaseEngine()
 {
     if (_baseEngine == null)
     {
         _baseEngine = TheThingRegistry.GetBaseEngine(EngineName);
     }
     return(_baseEngine);
 }
Example #6
0
        async void sinkReady()
        {
            TheCDEngines.RegisterNewMiniRelay("CHATSTER");
            var tThing = TheThingRegistry.GetBaseEngine("CHATSTER");

            tThing.RegisterEvent(eEngineEvents.IncomingMessage, HandleMessageAsync);
            await UpdateLog("SYSTEM: Connected to Cloud");
        }
        /// <summary>
        /// If this is a service the SimplexProc event will be called when the C-DEngine receives a new event sent by a subscriber to this service
        /// </summary>
        /// <param name="pMsg">The Message to be Processed</param>
        private void ProcessServiceMessage(TheProcessMessage pMsg)
        {
            string[] cmd = pMsg.Message.TXT.Split(':');
            switch (cmd[0]) //string 2 cases
            {
            case "WEBRELAY_RESPONSE":
                TheRequestData tState = TheCommonUtils.DeserializeJSONStringToObject <TheRequestData>(pMsg.Message.PLS);
                if (pMsg.Message.PLB != null && pMsg.Message.PLB.Length > 0)
                {
                    tState.ResponseBuffer = pMsg.Message.PLB;
                }
                tState.RequestUri = new Uri(tState.RequestUriString);
                //tState.SessionState = new TheSessionState() { SScopeID = pMsg.SID };
                sinkResults(tState);
                break;

            case "WEBRELAY_REQUEST":
                TheRequestData tData = TheCommonUtils.DeserializeJSONStringToObject <TheRequestData>(pMsg.Message.PLS);
                if (tData != null)
                {
                    tData.RequestUri = new Uri(tData.RequestUriString);
                    //tData.SessionState = new TheSessionState() { SScopeID = pMsg.SID };
                    if (pMsg.Message.PLB != null && pMsg.Message.PLB.Length > 0)
                    {
                        tData.PostData = pMsg.Message.PLB;
                    }
                    tData.CookieObject = pMsg.Message;
                    ReadHttpPage(tData, tData.SessionState.ARApp, null, sinkProcessResponse);
                    //InterceptHttpRequest(tData,tData.SessionState.ARApp);
                }
                break;

            case "WEBRELAY_REQUESTWRA":
                TSM             tTSM    = new TSM();
                List <TheThing> webApps = TheThingRegistry.GetThingsOfEngine(MyBaseEngine.GetEngineName());
                foreach (TheThing tApp in webApps)
                {
                    if (tApp.Address.Equals(pMsg.Message.PLS))
                    {
                        tTSM.PLS = $"/CDEWRA{tApp.cdeMID}" + TheThing.GetSafePropertyString(tApp, "HomePage");
                        break;
                    }
                }
                if (!string.IsNullOrEmpty(tTSM.PLS))
                {
                    string[]    org          = pMsg.Message.ORG.Split(':');
                    TheThing    senderThing  = TheThingRegistry.GetThingByMID(TheCommonUtils.CGuid(org[1]), true);
                    IBaseEngine senderEngine = TheThingRegistry.GetBaseEngine(senderThing, true);
                    tTSM.ENG = senderEngine.GetEngineName();
                    tTSM.TXT = "RESPONSEWRA";
                    TheCommCore.PublishToOriginator(pMsg.Message, tTSM, true);
                }
                break;
            }
        }
Example #8
0
        /// <summary>
        /// Virtual function that determines if a plugin has the rights to push back to a relay server from the cloud
        /// </summary>
        /// <param name="pMessage">Message to be inspected</param>
        /// <returns>True if the cloud can pushback, False prevents cloud from pushing back</returns>
        public virtual bool IsCloudAllowedToPushBack(TSM pMessage)
        {
            IBaseEngine tBase = TheThingRegistry.GetBaseEngine(pMessage.ENG);

            if (tBase == null || !tBase.GetEngineState().IsLiveEngine)
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
        internal static bool ParseSimplex(string pScopedTopic, TSM pMessage, TheQueuedSender pQSender) //, TheSessionState pSessionState, Action<TSM> pLocalCallback)
        {
            if (pMessage == null)
            {
                return(false);
            }
#if !JC_COMMDEBUG
            try
            {
#endif
            if (pMessage?.TXT?.Equals("CDE_DELETEORPHAN") == true)
            {
                TheQueuedSenderRegistry.RemoveOrphan(TheCommonUtils.CGuid(pMessage.PLS));
                return(false);
            }

            if (pQSender == null)
            {
                TheBaseAssets.MySYSLOG.WriteToLog(291, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("CoreComm", $"QSender not found! Received from ORG:{TheCommonUtils.GetDeviceIDML(pMessage?.ORG)}", eMsgLevel.l1_Error, pMessage?.PLS));
                return(false);
            }

            //SECURITY-REVIEW: This cannot be permitted without extra tokens and Encryption! otherwise it can be used to change a nodes scope on the fly!
            //if ("CDE_UPDATESCOPE".Equals(pMessage.TXT))
            //{
            //    pQSender.UpdateSubscriptionScope(TheBaseAssets.MyScopeManager.GetRealScopeID(pMessage.SID));     //GRSI: rare
            //    return true;
            //}
            if (pQSender != null && pMessage.ENG?.StartsWith(eEngineName.ContentService) == true && pMessage?.TXT == "CDE_SERVICE_INFO" && pQSender.MyTargetNodeChannel?.RealScopeID == TheBaseAssets.MyScopeManager.GetRealScopeID(pMessage.SID))
            {
                try
                {
                    pQSender.SetNodeInfo(TheCommonUtils.DeserializeJSONStringToObject <TheNodeInfoClone>(pMessage?.PLS));
                }
                catch (Exception e)
                {
                    TheBaseAssets.MySYSLOG.WriteToLog(23056, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("CoreComm", $"Error decoding SystemInfo {pQSender?.MyTargetNodeChannel?.ToMLString()}", eMsgLevel.l1_Error, e.ToString()));
                }
            }

            if (pMessage.TXT?.Equals("CDE_SUBSCRIBE") == true || pMessage.TXT?.Equals("CDE_INITIALIZE") == true) //9-9-2012 CDEC Did not work right on CDE_INIT
            {
                TheBaseAssets.MySYSLOG.WriteToLog(292, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("CoreComm", $"Parse-Simplex Subscribe from {pQSender?.MyTargetNodeChannel?.ToMLString()} Parsed: {pMessage?.PLS}", eMsgLevel.l7_HostDebugMessage));
                if (pQSender?.MyISBlock != null && !TheBaseAssets.MyServiceHostInfo.IsCloudService)
                {
                    TheBaseAssets.MySYSLOG.WriteToLog(292, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("CoreComm", "Parse-Simplex Subscribe rejected for Custom ISBConnect", eMsgLevel.l7_HostDebugMessage));
                    return(true);
                }
                ParseSubscribe(pMessage.PLS, pQSender);
                if (pMessage.ENG.Equals("CLOUDSYNC"))
                {
                    string[] tTopics = pMessage.PLS.Split(';');
                    foreach (string t in tTopics)
                    {
                        TSM.GetScrambledIDFromTopic(t, out string tEng);
                        if (TheThingRegistry.IsEngineRegistered(tEng))
                        {
                            IBaseEngine tsBase = TheThingRegistry.GetBaseEngine(tEng);
                            tsBase?.GetBaseThing()?.FireEvent(eEngineEvents.NewSubscription, tsBase.GetBaseThing(), pQSender.MyTargetNodeChannel, true);
                        }
                    }
                    return(true);
                }
                else
                {
                    TheThing tBase2 = TheThingRegistry.GetBaseEngineAsThing(pMessage.ENG);
                    if (tBase2 != null)
                    {
                        tBase2.FireEvent(eEngineEvents.NewSubscription, tBase2, pQSender.MyTargetNodeChannel, true);
                    }
                }
                if (pMessage.TXT.Equals("CDE_SUBSCRIBE"))       //NEW:2.06 Make sure Subscribe and Unsubscribe only go to first node
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            if (pMessage.TXT?.Equals("CDE_UNSUBSCRIBE") == true)
            {
                TheBaseAssets.MySYSLOG.WriteToLog(292, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("CoreComm", $"Parse-Simplex Unsubscribe from {pQSender.MyTargetNodeChannel?.ToMLString()} Parsed: {pMessage.PLS}", eMsgLevel.l7_HostDebugMessage));
                ParseUnsubscribe(pMessage.PLS, pQSender);
                return(true);       //NEW:2.06 Make sure Subscribe and Unsubscribe only go to first node
            }
#if !JC_COMMDEBUG
        }

        catch (Exception ee)
        {
            TheBaseAssets.MySYSLOG.WriteToLog(316, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("CoreComm", "Parse-Simplex", eMsgLevel.l1_Error, ee.ToString()));
        }
#endif
            return(false);
        }
Example #10
0
        private IEnumerable <TheThing> GetMatchingThings(Subscription subscription)
        {
            var things = new List <TheThing>();

            if (_thingReference.ThingMID.HasValue && _thingReference.ThingMID != Guid.Empty)
            {
                var thing = TheThingRegistry.GetThingByMID(_thingReference.ThingMID.Value, true);
                if (thing != null)
                {
                    things.Add(thing);
                }
                return(things);
            }

            IBaseEngine     baseEngine     = null;
            List <TheThing> matchingThings = null;

            if (!string.IsNullOrEmpty(_thingReference.EngineName))
            {
                baseEngine = TheThingRegistry.GetBaseEngine(_thingReference.EngineName);
                if (baseEngine == null)
                {
                    TheCDEngines.RegisterNewMiniRelay(_thingReference.EngineName);
                    baseEngine = TheThingRegistry.GetBaseEngine(_thingReference.EngineName);
                }
                if (baseEngine != null)
                {
                    subscription?.AddSubscription(baseEngine, this);
                    matchingThings = TheThingRegistry.GetThingsOfEngine(_thingReference.EngineName, true, true);
                }
            }
            else
            {
                object deviceTypeObj = null;
                if (_thingReference.PropertiesToMatch?.TryGetValue("DeviceType", out deviceTypeObj) == true)
                {
                    var deviceType = TheCommonUtils.CStr(deviceTypeObj);
                    if (!string.IsNullOrEmpty(deviceType))
                    {
                        matchingThings = TheThingRegistry.GetThingsByFunc("*", t => t.DeviceType.Equals(deviceType, StringComparison.Ordinal), true);
                    }
                }
            }

            if (matchingThings != null)
            {
                foreach (var thing in matchingThings)
                {
                    if (Matches(thing))
                    {
                        if (baseEngine == null)
                        {
                            subscription?.AddSubscription(thing.GetBaseEngine(), this);
                        }
                        things.Add(thing);
                    }
                }
            }

            return(things);
        }
Example #11
0
        private async Task RunPlaybackAsync(IEnumerable <cdeP> allProperties, IEnumerable <object> thingUpdates, TimeSpan startupDelayRange, bool bFromAutoStart, double propCountBefore)
        {
            for (int j = 1; j <= ReplayCount; j++)
            {
                playbackCancel?.Cancel();
                playbackCancel = new CancellationTokenSource();
                var cancelCombined = CancellationTokenSource.CreateLinkedTokenSource(playbackCancel.Token, TheBaseAssets.MasterSwitchCancelationToken);
                IsStarted = true;
                MyBaseThing.StatusLevel = 1;
                MyBaseThing.LastMessage = $"Playback started: {ItemCount} items. {ParallelPlaybackCount} things.";
                for (int i = 1; i <= ParallelPlaybackCount; i++)
                {
                    TheThing tThingOverride = null;
                    if (!string.IsNullOrEmpty(PlaybackEngineName))
                    {
                        if (TheThingRegistry.GetBaseEngine(PlaybackEngineName) == null)
                        {
                            TheCDEngines.RegisterNewMiniRelay(PlaybackEngineName);
                        }

                        var thingName = $"{MyBaseThing.FriendlyName}{i:D6}";
                        tThingOverride = TheThingRegistry.GetThingByID(PlaybackEngineName, thingName, true);
                        if (tThingOverride == null)
                        {
                            tThingOverride = new TheThing
                            {
                                FriendlyName = thingName,
                                ID           = thingName,
                                EngineName   = PlaybackEngineName,
                                DeviceType   = PlaybackDeviceType,
                            };

                            foreach (var prop in allProperties)
                            {
                                tThingOverride.SetProperty(prop.Name, prop.Value, prop.cdeT);
                            }
                            TheThingRegistry.RegisterThing(tThingOverride);
                        }
                        // This only works if the plug-in is actually installed, not with mini relay
                        //var createThingInfo = new TheThingRegistry.MsgCreateThingRequestV1
                        //{
                        //    EngineName = PlaybackEngineName,
                        //    DeviceType = PlaybackDeviceType,
                        //    InstanceId = thingName,
                        //    FriendlyName = thingName,
                        //    CreateIfNotExist = true,
                        //    DoNotModifyIfExists = true,
                        //    OwnerAddress = MyBaseThing,
                        //    Properties = new Dictionary<string, object> { { "ID", thingName } },
                        //};
                        //tThingOverride = await TheThingRegistry.CreateOwnedThingAsync(createThingInfo, new TimeSpan(0, 1, 0));
                        if (tThingOverride == null)
                        {
                            MyBaseThing.LastMessage = "Error creating playback thing";
                            break;
                        }
                    }
                    var playbackTask = TheCommonUtils.cdeRunTaskChainAsync($"Playback{i}", o => PlaybackLoop(tThingOverride, cancelCombined.Token, thingUpdates, startupDelayRange, bFromAutoStart), true);
                    playbackTasks.Add(playbackTask);
                }

                _ = await TheCommonUtils.TaskWhenAll(playbackTasks).ContinueWith(async(t) =>
                {
                    try
                    {
                        PlaybackDuration = sw.Elapsed;
                        sw.Stop();
                        OnKpiUpdate(null);
                        var propCount = Gen_Stats_PropertyCounter - propCountBefore;
                        var message   = $"Playback done. {propCount} props in {PlaybackDuration}. {propCount / PlaybackDuration.TotalSeconds} props/s. {ItemCount * ParallelPlaybackCount / PlaybackDuration.TotalSeconds} items/s.";
                        //MyBaseThing.LastMessage = message;
                        TheBaseAssets.MySYSLOG.WriteToLog(700, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyBaseThing.EngineName, message, eMsgLevel.l6_Debug));
                        await StopPlaybackAsync(message);
                        _ = new CDMyMeshManager.Contracts.MsgReportTestStatus
                        {
                            NodeId           = TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID,
                            PercentCompleted = (j * 1.0 / ReplayCount) * 100,
                            SuccessRate      = 100,
                            Status           = j == ReplayCount ? CDMyMeshManager.Contracts.eTestStatus.Success : CDMyMeshManager.Contracts.eTestStatus.Running,
                            TestRunId        = TheCommonUtils.CGuid(TheBaseAssets.MySettings.GetSetting("TestRunID")),
                            Timestamp        = DateTimeOffset.Now,
                            ResultDetails    = new Dictionary <string, object>
                            {
                                { "Message", message },
                                { "PropertyCount", propCount },
                                { "DurationInSeconds", PlaybackDuration.TotalSeconds }
                            },
                        }.Publish().Result;
                    }
                    catch { }
                }, TaskContinuationOptions.OnlyOnRanToCompletion);
            }
        }
Example #12
0
        /// <summary>
        /// Creates the basic NMI User Interface
        /// </summary>
        /// <returns></returns>
        public override bool CreateUX()
        {
            if (mIsUXInitCalled)
            {
                return(false);
            }

            mIsUXInitCalled = true;
            if (!MyBaseEngine.GetEngineState().IsService)
            {
                mIsUXInitialized = true;
                return(true);
            }

            UserPrefID = new Guid("{E15AE1F2-69F3-42DC-97E8-B0CC2A8526A6}").ToString().ToLower();
            UserManID  = TheThing.GetSafeThingGuid(MyBaseThing, "USEMAN").ToString().ToLower();
            AddDashboard(MyBaseThing, new TheDashboardInfo(eNMIPortalDashboard, "-HIDE")
            {
                FldOrder = 99999, PropertyBag = { "Category=NMI" }
            });                                                                                                                                   //Main Portal of Relay
            TheDashboardInfo tDash = AddDashboard(MyBaseThing, new TheDashboardInfo(eNMIDashboard, "NMI Admin Portal")
            {
                cdeA = 0x0, FldOrder = 9090, PropertyBag = new nmiDashboard()
                {
                    Category = "NMI", ForceLoad = true, Thumbnail = "FA5:f06c", Caption = "###NMI Admin###"
                }
            });

            if (!TheBaseAssets.MyServiceHostInfo.IsIsolated)
            {
                TheFormInfo tInf = new TheFormInfo(new Guid("{6EE8AC31-7395-4A80-B01C-D49BE174CFC0}"), eEngineName.NMIService, "###Service Overview###", "HostEngineStates")
                {
                    IsNotAutoLoading = true, PropertyBag = new nmiCtrlTableView {
                        ShowFilterField = true
                    }
                };
                AddFormToThingUX(tDash, MyBaseThing, tInf, "CMyTable", "###Service Overview###", 1, 0x0F, 128, "###NMI Administration###", null, new ThePropertyBag {
                    "TileThumbnail=FA5:f05a"
                });

                var tDisButName = "DISPLUG";
                var tDisBut     = AddSmartControl(MyBaseThing, tInf, eFieldType.TileButton, 1, 0x42, 0x80, null, "DisableText", new nmiCtrlTileButton()
                {
                    MID = new Guid("{7C67925E-7C2D-4460-9E61-6166494E9328}"), TableHeader = "###Is Enabled###", TileHeight = 1, TileWidth = 1, FldWidth = 1, ClassName = "cdeTableButton"
                });
                tDisBut.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, tDisButName, (sender, para) =>
                {
                    if (para is TheProcessMessage pMsg && pMsg.Message != null)
                    {
                        var tCmd = pMsg.Message.PLS?.Split(':');
                        if (tCmd != null && tCmd.Length > 2)
                        {
                            if (tCmd[1] != tDisButName)
                            {
                                return;
                            }
                            var estate = TheCDEngines.MyServiceStates.GetEntryByID(tCmd[2]);
                            if (estate != null)
                            {
                                var tBase = TheThingRegistry.GetBaseEngine(estate.ClassName);
                                if (tBase != null)
                                {
                                    if (tBase.HasCapability(eThingCaps.Internal))
                                    {
                                        TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", TheNMIEngine.LocNMI(pMsg, "###Not allowed on internal engines###")));
                                        return;
                                    }
                                    if (tBase.HasCapability(eThingCaps.MustBePresent))
                                    {
                                        TheCommCore.PublishToOriginator(pMsg.Message, new TSM(eEngineName.NMIService, "NMI_TOAST", TheNMIEngine.LocNMI(pMsg, "###Not allowed on engines that must be present###")));
                                        return;
                                    }
                                }
                                estate.IsDisabled = !estate.IsDisabled;
                                estate.IsUnloaded = estate.IsDisabled;
                                SetUXProperty(Guid.Empty, tDisBut.cdeMID, $"Caption={estate.DisableText}", pMsg.Message.PLS.Split(':')[2]);
                                TheBaseAssets.RecordServices();
                            }
                        }
                    }
                });