Esempio n. 1
0
        public bool RegisterRule(TheThingRule pRule)
        {
            if (pRule == null || TheBaseAssets.MyServiceHostInfo.IsCloudService)
            {
                return(false);
            }

            pRule.GetBaseThing().EngineName = MyBaseEngine.GetEngineName();
            if (pRule.TriggerCondition == eRuleTrigger.Set)
            {
                pRule.ActionValue = null;
            }
            pRule.IsRuleRunning        = false;
            pRule.IsRuleWaiting        = true;
            pRule.IsIllegal            = false;
            pRule.IsTriggerObjectAlive = false;
            pRule.Parent = MyBaseThing.ID;
            pRule.GetBaseThing().EngineName = MyBaseEngine.GetEngineName();
            TheSystemMessageLog.WriteLog(4445, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(eKnownDeviceTypes.TheThingRule, $"Rule {pRule.FriendlyName} stopped during Register Rule - waiting for startup"), false);

            TheThing.SetSafePropertyDate(pRule.GetBaseThing(), "LastTriggered", DateTimeOffset.MinValue);
            TheThing.SetSafePropertyDate(pRule.GetBaseThing(), "LastAction", DateTimeOffset.MinValue);
            TheThingRegistry.RegisterThing(pRule);
            return(true);
        }
Esempio n. 2
0
        void sinkThingWasUpdated(ICDEThing sender, object pPara)
        {
            if (TheBaseAssets.MyServiceHostInfo.IsCloudService)
            {
                return;                                                 //TODO: Allow Cloud Rules
            }
            TheThing pThing = sender as TheThing;

            if (pThing != null && TheThing.GetSafePropertyString(pThing, "DeviceType") == eKnownDeviceTypes.TheThingRule)
            {
                TheRule tRule = pThing.GetObject() as TheRule;
                if (tRule == null)
                {
                    tRule = new TheRule(pThing, this);
                    tRule.RegisterEvent(eEngineEvents.ThingUpdated, sinkUpdated);
                    RegisterRule(tRule);
                }

                {
                    tRule.IsRuleWaiting = true;
                    tRule.IsRuleRunning = false;
                    TheSystemMessageLog.WriteLog(4445, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(eKnownDeviceTypes.TheThingRule, $"Rule {tRule.FriendlyName} stopped on Rule Update"), false);

                    TheThingRegistry.UpdateThing(tRule, false);
                }
                ActivateRules();
            }
        }
        static readonly TimeSpan defaultRequestTimeout = new TimeSpan(0, 1, 0); // TODO make this configurable?

        /// <summary>
        /// Sends a TSM message to the targetThing and return the matching response message
        /// </summary>
        /// <param name="originator">Thing or engine to use for response messages. If NULL defaults to ContentService.</param>
        /// <param name="target">Thing or engine to which the message is to be sent.</param>
        /// <param name="messageName">Name of the message, as defined by the target thing. The response message will be messageName_RESPONSE.</param>
        /// <param name="txtParameters">Array of simple string parameters, to be attached to the message's TXT field, as defined by the target thing. txtParameters must not contain ":" characters.</param>
        /// <param name="PLS">String payload to be set as the message's PLS field, as defined by the target thing.</param>
        /// <param name="PLB">Binary pauload to be set as the message's PLB field, as defined by the target thing.</param>
        /// <param name="timeout">Time to wait for the response message. Can not exceed TheBaseAsset.MaxMessageResponseTimeout (default: 1 hour).</param>
        /// <returns>The response message as defined by the target thing. The response parameters and correlation token can be parsed using ParseRequestOrResponseMessage, if the target thing used the PublishResponseMessage or an equivalent message format.
        /// If the message times out or an error occured while sending the message, the return value will be null.
        /// </returns>
        public static Task <TSM> PublishRequestAsync(TheMessageAddress originator, TheMessageAddress target, string messageName, TimeSpan timeout, string[] txtParameters = null, string PLS = null, byte[] PLB = null)
        {
            Guid correlationToken = Guid.NewGuid();

            if (originator == null)
            {
                originator = TheThingRegistry.GetBaseEngineAsThing(eEngineName.ContentService);
            }
            var msg = PrepareRequestMessage(originator, target, messageName, correlationToken, txtParameters, PLS, PLB);

            if (msg == null)
            {
                return(null);
            }

            if (timeout > MaxTimeOut)
            {
                timeout = MaxTimeOut;
            }
            if (timeout == TimeSpan.Zero)
            {
                timeout = defaultRequestTimeout;
            }

            var tcsResponse = new TaskCompletionSource <TSM>();

            var callback = new Action <ICDEThing, object>((tSenderThing, responseMsgObj) =>
            {
                var responseMsg = CheckResponseMessage(messageName, correlationToken, responseMsgObj);
                if (responseMsg != null)
                {
                    var bReceived = tcsResponse.TrySetResult(responseMsg);
                    if (bReceived)
                    {
                        TheSystemMessageLog.WriteLog(1000, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("Thing Registry", $"Processed response message for {messageName}", eMsgLevel.l2_Warning, $"{correlationToken}: {responseMsg?.TXT}"), false);
                    }
                    else
                    {
                        TheSystemMessageLog.WriteLog(1000, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("Thing Registry", $"Failed to process response message for {messageName}: timed out or double response", eMsgLevel.l2_Warning, $"{correlationToken}: {responseMsg?.TXT}"), false);
                    }
                }
                else
                {
                    responseMsg = (responseMsgObj as TheProcessMessage)?.Message;
                    TheSystemMessageLog.WriteLog(1000, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("Thing Registry", $"Ignoring response message for {messageName}", eMsgLevel.l2_Warning, $"{correlationToken}: {responseMsg?.TXT}"), false);
                }
            });

            var originatorThingOrEngine = RegisterRequestCallback(originator, callback);

            if (originatorThingOrEngine == null)
            {
                return(null);
            }

            if (target.SendToProvisioningService)
            {
                TheISMManager.SendToProvisioningService(msg);
            }
            else if (target.Node != Guid.Empty)
            {
                TheCommCore.PublishToNode(target.Node, msg);
            }
            else
            {
                TheCommCore.PublishCentral(msg, true);
            }

            TheCommonUtils.TaskWaitTimeout(tcsResponse.Task, timeout).ContinueWith((t) =>
            {
                UnregisterRequestCallback(originatorThingOrEngine, callback);
                var timedOut = tcsResponse.TrySetResult(null); // Will preserve value if actual result has already been set
                if (timedOut)
                {
                    TheSystemMessageLog.WriteLog(1000, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("Thing Registry", $"Timeout waiting for response message for {messageName}", eMsgLevel.l2_Warning, $"{correlationToken}"), false);
                }
            });
            return(tcsResponse.Task);
        }
Esempio n. 4
0
        public bool ActivateRules()
        {
            if (TheCDEngines.MyThingEngine == null || TheBaseAssets.MyServiceHostInfo.IsCloudService || TheCommonUtils.cdeIsLocked(LockRules) || !mIsInitialized)
            {
                return(false);
            }

            lock (LockRules)
            {
                if (mIsInitialized)
                {
                    InitRules();
                }
                //List<TheRule> tList = MyRulesStore.MyMirrorCache.GetEntriesByFunc(s => s.IsRuleActive && !s.IsRuleRunning && s.IsRuleWaiting);
                List <TheThing> tList = TheThingRegistry.GetThingsByFunc("*", s =>
                                                                         TheThing.GetSafePropertyString(s, "Parent").Equals(MyBaseThing.ID) && //TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID) &&
                                                                         TheThing.GetSafePropertyBool(s, "IsRuleActive") &&
                                                                         !TheThing.GetSafePropertyBool(s, "IsRuleRunning") &&
                                                                         TheThing.GetSafePropertyBool(s, "IsRuleWaiting"));
                if (tList != null && tList.Count > 0)
                {
                    foreach (TheThing tThing in tList)
                    {
                        TheRule tRule = tThing.GetObject() as TheRule;
                        if (tRule == null)
                        {
                            continue;
                        }
                        if (string.IsNullOrEmpty(tRule.TriggerProperty))
                        {
                            tRule.IsIllegal     = true;
                            tRule.IsRuleWaiting = false;
                            continue;
                        }
                        if (tRule.TriggerStartTime > DateTimeOffset.Now)
                        {
                            continue;
                        }
                        if (tRule.TriggerEndTime < DateTimeOffset.Now)
                        {
                            RemoveTrigger(tRule, false);
                            continue;
                        }
                        switch (tRule.TriggerObjectType)
                        {
                        case "CDE_ENGINE":
                            TheThing tBase = TheThingRegistry.GetBaseEngineAsThing(tRule.TriggerObject);
                            if (tBase != null)
                            {
                                tBase.RegisterEvent(eEngineEvents.IncomingMessage, sinkRuleIncoming);
                                tRule.IsRuleWaiting        = false;
                                tRule.IsRuleRunning        = true;
                                tRule.IsTriggerObjectAlive = true;
                                TheSystemMessageLog.WriteLog(4445, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(eKnownDeviceTypes.TheThingRule, $"Rule {tRule.FriendlyName} started with TriggerType: {tRule.TriggerObjectType}"), false);
                            }
                            break;

                        case "CDE_EVENTFIRED":
                            TheThing tBaseE = TheThingRegistry.GetBaseEngineAsThing(tRule.TriggerObject);
                            if (tBaseE != null)
                            {
                                tBaseE.RegisterEvent(tRule.TriggerProperty, sinkRuleThingEvent);
                                tRule.IsRuleWaiting        = false;
                                tRule.IsRuleRunning        = true;
                                tRule.IsTriggerObjectAlive = true;
                                TheSystemMessageLog.WriteLog(4445, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(eKnownDeviceTypes.TheThingRule, $"Rule {tRule.FriendlyName} started with TriggerType: {tRule.TriggerObjectType}"), false);
                            }
                            break;

                        default:
                            TheThing tTriggerThing = TheThingRegistry.GetThingByMID("*", TheCommonUtils.CGuid(tRule.TriggerObject));
                            if (tTriggerThing != null)
                            {
                                //if (tTriggerThing.GetObject() == null) continue;  //TODO: Verify if this can stay removed
                                //if (tTriggerThing.GetProperty("FriendlyName").Value.ToString().Contains("Motion")) continue;
                                cdeP tProp = tTriggerThing.GetProperty(tRule.TriggerProperty, true);
                                if (tProp != null)
                                {
                                    tProp.UnregisterEvent(eThingEvents.PropertyChanged, sinkRuleAction);
                                    tProp.RegisterEvent(eThingEvents.PropertyChanged, sinkRuleAction);
                                }
                                tRule.IsRuleWaiting        = false;
                                tRule.IsRuleRunning        = true;
                                tRule.IsTriggerObjectAlive = true;
                                tRule.RuleTrigger(tProp.ToString(), true);
                                TheSystemMessageLog.WriteLog(4445, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(eKnownDeviceTypes.TheThingRule, $"Rule {tRule.FriendlyName} started with TriggerType: {tRule.TriggerObjectType}"), false);
                            }
                            break;
                        }
                    }
                }
            }
            return(true);
        }