// Register for history on our Thing public void ConsumeHistory() { if (testThing != null) { TheHistoryParameters historyParameters = new TheHistoryParameters { Properties = properties, SamplingWindow = TimeSpan.FromMilliseconds(5000), // Every 5 seconds ReportUnchangedProperties = true, ReportInitialValues = true, Persistent = true, MaintainHistoryStore = false, ComputeAvg = true, ComputeMax = true, ComputeMin = true }; historyToken = testThing.RegisterForUpdateHistory(historyParameters); TheQueuedSenderRegistry.RegisterHealthTimer((l) => { // Every 6 seconds, log the aggregated values. Sampling window for historian is 5 seconds. if (l % 6 == 0) { LogChanges(true); } }); } }
public virtual TheHistoryParameters GetHistoryParameters() { var propsIncluded = this.GetPropsIncluded(); if (!propsIncluded?.Any() == true) { propsIncluded = null; } var propsExcluded = this.GetPropsExcluded(); if (!propsExcluded?.Any() == true) { propsExcluded = null; } var historyParams = new TheHistoryParameters { TokenExpiration = this.TokenExpirationInHours.HasValue ? new TimeSpan?(new TimeSpan((int)this.TokenExpirationInHours, 0, 0)) : null, MaxCount = this.MaxHistoryCount, MaxAge = new TimeSpan(0, 0, 0, 0, (int)this.MaxHistoryTime), Properties = propsIncluded, PropertiesToExclude = propsExcluded, FilterToConfigProperties = (GetThing()?.Capabilities.Contains(eThingCaps.ConfigManagement) ?? false) && ForceAllProperties != true && ForceConfigProperties == true, FilterToSensorProperties = (GetThing()?.Capabilities.Contains(eThingCaps.SensorContainer) ?? false) && ForceAllProperties != true, SamplingWindow = new TimeSpan(0, 0, 0, 0, (int)this.ChangeBufferTimeBucketSize), CooldownPeriod = new TimeSpan(0, 0, 0, 0, (int)this.ChangeBufferLatency), ReportUnchangedProperties = this.SendUnchangedValue, ReportInitialValues = this.SendInitialValues, Persistent = this.KeepDurableHistory, IgnoreExistingHistory = this.IgnoreExistingHistory, //MaintainHistoryStore = false, }; return(historyParams); }
public static bool CanSatisfy(TheHistoryParameters param, TheHistoryParameters param2) { var result = (param.ComputeAvg == false || param.ComputeAvg == param2.ComputeAvg) && (param.ComputeMax == false || param.ComputeMax == param2.ComputeMax) && (param.ComputeN == false || param.ComputeN == param2.ComputeN) && param.CooldownPeriod == param2.CooldownPeriod && param.MaintainHistoryStore == param2.MaintainHistoryStore && param.ExternalHistoryStore == param2.ExternalHistoryStore && param.MaxAge == param2.MaxAge && param.MaxCount == param2.MaxCount && param.Persistent == param2.Persistent && (param.Properties == null || (param2.Properties != null && param2.Properties.Intersect(param.Properties).Count() == param2.Properties.Count())) && (param.PropertiesToExclude == null || param2.PropertiesToExclude == null || param2.PropertiesToExclude.Intersect(param.PropertiesToExclude).Count() == 0) && param.ReportUnchangedProperties == param2.ReportUnchangedProperties && param.SamplingWindow == param2.SamplingWindow ; return(result); }
/// <summary> /// Creates a copy of a TheThingStore with a selectable subset of properties. /// </summary> /// <param name="thingWithMeta">An optional thing with meta information like Sensor or Config property information.</param> /// <param name="baseItem">Optional TheThingStore with additional properties to copy into the clone.</param> /// <param name="ResetBase">Creates a new cdeMID and timestamp. Otherwise the item will have the same cdeMID and timestamp as the baseItem. </param> /// <param name="propFilter">Specification of which properties to copy. If null, all properties will be copied.</param> /// <param name="forExternalConsumption">Set a flag that is used by the Historian mechanism internally.</param> /// <param name="bUpdated">Returns true if an of the baseItem properties overwrote properties in the TheThingStore.</param> /// <returns>The copy of the baseItem TheThingStore</returns> internal TheThingStore CloneForThingSnapshot(TheThing thingWithMeta, TheThingStore baseItem, bool ResetBase, TheHistoryParameters propFilter, bool forExternalConsumption, out bool bUpdated) { TheThingStore tThing = new TheThingStore(); if (ResetBase) { tThing.cdeCTIM = DateTimeOffset.Now; tThing.cdeMID = Guid.NewGuid(); } else { tThing.cdeCTIM = cdeCTIM; tThing.cdeMID = cdeMID; } tThing.cdeAVA = cdeAVA; tThing.cdeA = cdeA; if (baseItem != null && baseItem.cdeEXP != 0 && cdeEXP == 0) { tThing.cdeEXP = baseItem.cdeEXP; } else { tThing.cdeEXP = cdeEXP; } tThing.cdePRI = cdePRI; tThing.cdeF = cdeF; tThing.cdeM = cdeM; tThing.cdeN = cdeN; tThing.cdeO = cdeO; tThing.cdeSEQ = cdeSEQ; IEnumerable <string> propertiesToInclude = null; if (propFilter?.Properties != null || propFilter.FilterToSensorProperties == true || propFilter.FilterToConfigProperties == true) { propertiesToInclude = thingWithMeta?.GetMatchingProperties(propFilter); if (propertiesToInclude != null) { if (propFilter.ComputeMax) { propertiesToInclude = propertiesToInclude.Concat(propertiesToInclude.Select(propName => $"[{propName}].Max")); } if (propFilter.ComputeAvg) { propertiesToInclude = propertiesToInclude.Concat(propertiesToInclude.Select(propName => $"[{propName}].Avg")); } if (propFilter.ComputeMin) { propertiesToInclude = propertiesToInclude.Concat(propertiesToInclude.Select(propName => $"[{propName}].Min")); } if (propFilter.ComputeN) { propertiesToInclude = propertiesToInclude.Concat(propertiesToInclude.Select(propName => $"[{propName}].N")); } } } if (propertiesToInclude == null) { propertiesToInclude = baseItem != null?baseItem.PB.Keys.Union(PB.Keys) : PB.Keys; if (propFilter?.PropertiesToExclude?.Any() == true) { var tempList = new List <string>(propertiesToInclude); foreach (var prop in propFilter.PropertiesToExclude) { tempList.Remove(prop); } propertiesToInclude = tempList; } } bUpdated = false; foreach (string key in propertiesToInclude) { if (PB.ContainsKey(key)) { bUpdated = true; tThing.PB[key] = PB[key]; } else if (baseItem != null && baseItem.PB.ContainsKey(key)) { try { tThing.PB[key] = baseItem.PB[key]; } catch (Exception) { //ignored } } } if (forExternalConsumption) { tThing.IsFullSnapshot = false; tThing.IsInitialValue = false; } else { if (IsFullSnapshot || (baseItem != null && baseItem.IsFullSnapshot)) { tThing.IsFullSnapshot = true; } } if (!bUpdated && baseItem != null) { return(null); // all properties came from the baseItem, which means the thing update didn't have any matching property changes } return(tThing); }