/// <summary>
 /// Activates a given rule
 /// </summary>
 /// <param name="pRuleID">ID To activate</param>
 /// <param name="pTurnActive">if true, the rule will be activated otherwise deactivated</param>
 /// <returns></returns>
 public static bool ActivateRule(Guid pRuleID, bool pTurnActive)
 {
     InitRR();
     if (MyRulesRegistry != null)
     {
         ICDEThing pRule = TheThingRegistry.GetThingByID(eEngineName.ThingService, pRuleID.ToString());
         if (pRule != null)
         {
             try
             {
                 if (pRule.GetBaseThing().GetObject() is TheThingRule tRule)
                 {
                     tRule.IsRuleActive = pTurnActive;
                     MyRulesRegistry.ActivateRules();
                     return(true);
                 }
             }
             catch
             {
                 //ignored
             }
         }
     }
     return(false);
 }
        void sinkUpdated(ICDEThing sender, object inObj)
        {
            if (TheBaseAssets.MyServiceHostInfo.IsCloudService)
            {
                return;
            }

            TheThing pThing = sender.GetBaseThing();

            if (pThing != null)
            {
                TheRule tRule = pThing.GetObject() as TheRule;
                if (tRule != null)
                {
                    if (tRule.IsRuleActive)
                    {
                        ActivateRules();
                    }
                    else
                    {
                        RemoveTrigger(tRule, true);
                    }
                }
            }
        }
Exemple #3
0
        private void WriteAggregatedConditionsToProperty(ICDEThing tEventHost, DateTimeOffset time)
        {
            var currentConditionsAsJson = TheCommonUtils.SerializeObjectToJSONString(_currentConditionsByConditionId.Values.OrderByDescending(evnt =>
            {
                if (evnt.TryGetValue("Time", out var evntTime))
                {
                    return(evntTime);
                }
                return(null);
            }).ToList());

            if (TheThing.GetSafePropertyString(tEventHost.GetBaseThing(), DisplayName) != currentConditionsAsJson)
            {
                TheBaseAssets.MySYSLOG.WriteToLog(78102, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(MyOPCServer.GetBaseThing().EngineName, $"Updated current events {_currentConditionsByConditionId.Count} - {currentConditionsAsJson}", eMsgLevel.l6_Debug, $"{DisplayName} {GetNodeIdForLogs()} {EventInfo.AggregateRetainedConditions}"));
                // Using publish time because the event timestamps could be way in the past (i.e. when a recent event just was removed)
                tEventHost.GetBaseThing().SetProperty(DisplayName, currentConditionsAsJson, time);
            }
            else
            {
                TheBaseAssets.MySYSLOG.WriteToLog(78102, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(MyOPCServer.GetBaseThing().EngineName, $"No change to current events {_currentConditionsByConditionId.Count} - {currentConditionsAsJson}", eMsgLevel.l6_Debug, $"{DisplayName} {GetNodeIdForLogs()} {EventInfo.AggregateRetainedConditions}"));
            }
        }
 /// <summary>
 /// Probes if a rule with the given ID exists
 /// </summary>
 /// <param name="pRuleID">ID to probe for</param>
 /// <returns></returns>
 public static bool HasRuleID(Guid pRuleID)
 {
     InitRR();
     if (MyRulesRegistry != null)
     {
         ICDEThing pRule = TheThingRegistry.GetThingByID(eEngineName.ThingService, pRuleID.ToString());
         if (pRule != null)
         {
             try
             {
                 if (pRule.GetBaseThing().GetObject() is TheThingRule tRule)
                 {
                     return(true);
                 }
             }
             catch
             {
                 //ignored
             }
         }
     }
     return(false);
 }
Exemple #5
0
        /// <summary>
        /// Clones all TheThing properties and returns a TheThingStore class
        /// </summary>
        /// <param name="iThing">The Thing to clone.</param>
        /// <param name="ResetBase">Use current time instead of Thing timestamp</param>
        /// <param name="bUsePropertyTimestamp">Use latest timestamp of any of the properties</param>
        /// <param name="cloneProperties">Indiciates if current properties and their of the iThing should be added to TheThingStore.PB of only an empty PB should be returned.</param>
        /// <param name="cloneFilter">When cloning, indicates which properties to include. If null, all properties of the thing are included.</param>
        /// <returns></returns>
        internal static TheThingStore CloneFromTheThingInternal(ICDEThing iThing, bool ResetBase, bool bUsePropertyTimestamp, bool cloneProperties, ThePropertyFilter cloneFilter)
        {
            TheThingStore tThing = new TheThingStore();

            if (iThing == null)
            {
                return(tThing);
            }
            TheThing pThing = iThing.GetBaseThing();

            if (pThing != null)
            {
                if (ResetBase)
                {
                    tThing.cdeCTIM = !bUsePropertyTimestamp ? DateTimeOffset.Now : DateTimeOffset.MinValue;
                    tThing.cdeMID  = Guid.NewGuid();
                }
                else
                {
                    tThing.cdeCTIM = pThing.cdeCTIM;
                    tThing.cdeMID  = pThing.cdeMID;
                }
                tThing.cdeAVA = pThing.cdeAVA;
                tThing.cdeA   = pThing.cdeA;
                tThing.cdeEXP = pThing.cdeEXP;
                tThing.cdePRI = pThing.cdePRI;
                tThing.cdeF   = pThing.cdeF;
                tThing.cdeM   = pThing.cdeM;
                tThing.cdeN   = pThing.cdeN;
                //tThing.cdeO = pThing.cdeO;
                tThing.cdeO = pThing.cdeMID;    //CODE-REVIEW: Since tThing is a "TheThingStore" and is "owned" by the pThing, the cdeO (Owner) property should be updated. Does this break anything for TDS01 etc???
                //tThing.OwnerThingMID = pThing.cdeMID; //Alternative we need to add a OwnerThingMID to TheThingStore to be able to segregate retrieval of TheThingStore records from the SQL Server
                tThing.cdeSEQ = pThing.cdeSEQ;

                if (cloneProperties)
                {
                    var propertiesToInclude = pThing.GetMatchingProperties(cloneFilter);

                    int propsIncludeCount = 0;
                    foreach (string key in propertiesToInclude)
                    {
                        try
                        {
                            cdeP prop;
                            if ((prop = pThing.GetProperty(key)) != null) // .MyPropertyBag.TryGetValue(key, out prop))
                            {
                                //if (prop.CheckAndResetTouchedSinceLastHistorySnapshot() || cloneProperties) // Have to always check and reset, so do this first
                                {
                                    tThing.PB[key] = prop.Value;
                                    if (bUsePropertyTimestamp)
                                    {
                                        if (prop.cdeCTIM > tThing.cdeCTIM)
                                        {
                                            if (tThing.cdeCTIM.Ticks != 0 && tThing.PB.Count > 1)
                                            {
                                                TheBaseAssets.MySYSLOG.WriteToLog(1, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(eEngineName.ThingService, "Historian timestamp changed by property when cloning for snapshot", eMsgLevel.l6_Debug, $"{prop.Name}: {tThing.cdeCTIM:O} changed to {prop.cdeCTIM:O}. Possible victims: {tThing.PB.Aggregate("", (s, kv) => kv.Key != prop.Name ? $"{s}{kv.Key}," : s)}"));
                                            }
                                            tThing.cdeCTIM = prop.cdeCTIM;
                                        }
                                        else if (prop.cdeCTIM != tThing.cdeCTIM)
                                        {
                                            TheBaseAssets.MySYSLOG.WriteToLog(1, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(eEngineName.ThingService, "Historian timestamp on property not applied when cloning for snapshot", eMsgLevel.l6_Debug, $"{prop.Name}: {prop.cdeCTIM:O} changed to {tThing.cdeCTIM:O}. Possible offenders: {tThing.PB.Aggregate("", (s, kv) => kv.Key != prop.Name ? $"{s}{kv.Key}," : s)}"));
                                        }
                                    }
                                }
                            }
                        }
                        catch (Exception)
                        {
                            //ignored
                        }
                        propsIncludeCount++;
                    }

                    if (tThing.cdeCTIM == DateTimeOffset.MinValue)
                    {
                        tThing.cdeCTIM = pThing.cdeCTIM;
                    }

                    // We have all properties that are available in the thing as of this time and that are requested: this snapshot can and will now be used as the basis to report unchanged properties
                    tThing.IsFullSnapshot = true;
                }
            }
            return(tThing);
        }