public override void DoCreateUX(TheFormInfo tMyForm, ThePropertyBag pChartsBag = null) { base.DoCreateUX(tMyForm); AddSpeedGauge(tMyForm); var tEngage = TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.TileButton, 25012, 2, 0xC0, "Restart KPI", null, new nmiCtrlNumber { ParentFld = TheDefaultSensor.SensorActionArea, TileWidth = 6, NoTE = true }); tEngage.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "reset", (sender, para) => { EngageMapper(); }); var tRemove = TheNMIEngine.AddSmartControl(MyBaseThing, tMyForm, eFieldType.TileButton, 25013, 2, 0xC0, "Delete this KPI Report", null, new nmiCtrlNumber { ParentFld = TheDefaultSensor.SensorActionArea, TileWidth = 6, NoTE = true }); tRemove.RegisterUXEvent(MyBaseThing, eUXEvents.OnClick, "remove", (sender, para) => { TheThing tT = TheThingRegistry.GetThingByID(MyBaseEngine.GetEngineName(), MyBaseThing.ID); if (tT != null) { TheThingRegistry.UnmapPropertyMapper(mRealThingGuid); TheThingRegistry.DeleteThing(tT); } }); }
public void TestSensorProviderModel() { var deviceTypes = TheThingRegistry.GetAllDeviceTypesByCap(nsCDEngine.ViewModels.eThingCaps.SensorProvider, true); Assert.Greater(deviceTypes.Count, 0, "No sensor provider device types found"); foreach (var deviceType in deviceTypes) { TestInfo testInfo; var provider = CreateThingForTest(deviceType, out testInfo); WriteLine($"{deviceType}: Provider created"); if (testInfo.PreTestSubscriptions != null) { var subscribeResponse = provider.SubscribeSensorsAsync(new TheThing.MsgSubscribeSensors { SubscriptionRequests = testInfo.PreTestSubscriptions, ReplaceAll = false, DefaultTargetThing = provider }).Result; Assert.IsNotNull(subscribeResponse, "Timeout or subscribe message not implemented by plug-in"); Assert.IsTrue(string.IsNullOrEmpty(subscribeResponse.Error), $"Error from SubscribeSensors: {subscribeResponse.Error}"); } int subscriptionCount = BrowseAndSubscribeAllSensors(provider, null, testInfo.MaximumBrowseTags, testInfo.MinimumBrowseTags, out var browseResponse, out var sensorSubscriptionResponse, out var successfullSubscriptions); var getSubscriptionResponse = provider.GetSensorProviderSubscriptionsAsync().Result; Assert.IsNotNull(getSubscriptionResponse, "Timeout or get subscriptions message not implemented by plug-in"); Assert.IsTrue(string.IsNullOrEmpty(getSubscriptionResponse.Error), $"Error from GetSensorSubscriptions: {getSubscriptionResponse.Error}"); Assert.AreEqual(subscriptionCount, getSubscriptionResponse.Subscriptions.Count, $"Subscription count doesn't match for {deviceType}"); if (sensorSubscriptionResponse.SubscriptionStatus.Count > 0) { var subscriptionIdToUnsubscribe = sensorSubscriptionResponse.SubscriptionStatus[0].Subscription.SubscriptionId ?? Guid.Empty; var unsubscribeRequest = new TheThing.MsgUnsubscribeSensors { SubscriptionIds = new List <Guid> { subscriptionIdToUnsubscribe }, }; var unsubscribeResponse = provider.UnsubscribeSensorsAsync(unsubscribeRequest).Result; Assert.IsNotNull(unsubscribeResponse, "Timeout or unsubscribe message not implemented by plug-in"); Assert.IsTrue(string.IsNullOrEmpty(unsubscribeResponse.Error), $"{deviceType}: Error from UnsubscribeSensors for {subscriptionIdToUnsubscribe}: {unsubscribeResponse.Error}"); Assert.AreEqual(0, unsubscribeResponse.Failed?.Count ?? 0); } else { WriteLine($"{deviceType}: No subscriptions found after subscribe request"); } TheThingRegistry.DeleteThing(provider); } }
public void TestConfigModel() { var deviceTypes = TheThingRegistry.GetAllDeviceTypesByCap(nsCDEngine.ViewModels.eThingCaps.ConfigManagement, true); foreach (var deviceType in deviceTypes) { WriteLine($"{deviceType}: Starting test."); TestInfo testInfo; var configThing = CreateThingForTest(deviceType, out testInfo); WriteLine($"{deviceType}: Provider created"); int subscriptionCount; if (configThing.Capabilities.Contains(nsCDEngine.ViewModels.eThingCaps.SensorProvider)) { subscriptionCount = BrowseAndSubscribeAllSensors(configThing, null, testInfo.MaximumBrowseTags, testInfo.MinimumBrowseTags, out var browseResponse, out var sensorSubscriptionResponse, out var successfullSubscriptions); WriteLine($"{deviceType}: Browsed and subscribed to {subscriptionCount} source sensors"); } else { WriteLine($"{deviceType}: Not a sensor provider: skipping browse and subscribe"); subscriptionCount = 0; } { var exportedConfig = configThing.GetThingConfigurationAsync(false).Result; Assert.IsNotNull(exportedConfig, $"Timeout or subscribe message not implemented by plug-in: {deviceType}"); //Assert.IsTrue(string.IsNullOrEmpty(exportedConfig.Error)); // TODO Add an error property to TheThingConfiguration? Assert.AreEqual(subscriptionCount, exportedConfig.SensorSubscriptions?.Count ?? 0); Assert.Greater(exportedConfig.ConfigurationValues.Count, 0, $"No config properties returned: {deviceType}"); var configAsJson = TheCommonUtils.SerializeObjectToJSONString(exportedConfig); WriteLine($"{deviceType}: Generated configuration export with {exportedConfig.ConfigurationValues.Count} settings, {exportedConfig.SensorSubscriptions?.Count ?? 0} sensor subscriptions: " + "{0}", configAsJson); } { var exportedGeneralizedConfig = configThing.GetThingConfigurationAsync(true).Result; Assert.IsNotNull(exportedGeneralizedConfig, $"Timeout or subscribe message not implemented by plug-in: {deviceType}"); //Assert.IsTrue(string.IsNullOrEmpty(exportedConfig.Error)); // TODO Add an error property to TheThingConfiguration? Assert.AreEqual(subscriptionCount, exportedGeneralizedConfig.SensorSubscriptions?.Count ?? 0); Assert.Greater(exportedGeneralizedConfig.ConfigurationValues.Count, 0, $"No config properties returned: {deviceType}"); var configAsJson = TheCommonUtils.SerializeObjectToJSONString(exportedGeneralizedConfig); WriteLine($"{deviceType}: Generated generalized configuration with {exportedGeneralizedConfig.ConfigurationValues.Count} settings, {exportedGeneralizedConfig.SensorSubscriptions?.Count ?? 0} sensor subscriptions: " + "{0}", configAsJson); } TheThingRegistry.DeleteThing(configThing); } }
public void TestSensorPipeline() { var sensorThing = new TheThing { EngineName = "CDMyVThings.TheVThings", DeviceType = "Memory Tag", ID = "TestSensorThing03" }; TheThingRegistry.RegisterThing(sensorThing); //sensorThing = TheThingRegistry.GetThingByMID(sensorThing.cdeMID); // Make all providers send properties into the memory thing var providers = new List <TheThing>(); { var deviceTypes = TheThingRegistry.GetAllDeviceTypesByCap(nsCDEngine.ViewModels.eThingCaps.SensorProvider, true); Assert.Greater(deviceTypes.Count, 0, "No sensor provider device types found"); foreach (var deviceType in deviceTypes) { TestInfo testInfo; var provider = CreateThingForTest(deviceType, out testInfo); WriteLine($"{deviceType}: Provider created"); int subscriptionCount = BrowseAndSubscribeAllSensors(provider, sensorThing, testInfo.MaximumBrowseTags, testInfo.MinimumBrowseTags, out var browseResponse, out var sensorSubscriptionResponse, out var successfullSubscriptions); var getSubscriptionResponse = provider.GetSensorProviderSubscriptionsAsync().Result; Assert.IsNotNull(getSubscriptionResponse, "Timeout or get subscriptions message not implemented by plug-in"); Assert.IsTrue(string.IsNullOrEmpty(getSubscriptionResponse.Error), $"Error from GetSensorSubscriptions: {getSubscriptionResponse.Error}"); Assert.AreEqual(subscriptionCount, getSubscriptionResponse.Subscriptions.Count); if (sensorSubscriptionResponse.SubscriptionStatus.Count <= 0) { WriteLine($"{deviceType}: No subscriptions found after subscribe request"); } providers.Add(provider); } } var consumers = new List <TheThing>(); { var deviceTypes = TheThingRegistry.GetAllDeviceTypesByCap(nsCDEngine.ViewModels.eThingCaps.SensorConsumer, true); Assert.Greater(deviceTypes.Count, 0, "No sensor consumer device types found"); foreach (var deviceType in deviceTypes) { TestInfo testInfo; var consumer = CreateThingForTest(deviceType, out testInfo); WriteLine($"{deviceType}: Consumer created"); var thingSubscriptions = new List <TheThing.TheThingSubscription> { new TheThing.TheThingSubscription { ThingReference = sensorThing, }, }; { var subscribeToThingsResponse = consumer.SubscribeToThingsAsync(thingSubscriptions).Result; Assert.NotNull(subscribeToThingsResponse, $"Timeout or subscribe to things message not implemented by consumer {deviceType}"); Assert.IsTrue(string.IsNullOrEmpty(subscribeToThingsResponse.Error), $"Error from consumer {deviceType}: {subscribeToThingsResponse.Error}"); Assert.GreaterOrEqual(thingSubscriptions.Count, subscribeToThingsResponse.SubscriptionStatus.Count, $"Not enough status reports for {deviceType}"); foreach (var subStatus in subscribeToThingsResponse.SubscriptionStatus) { Assert.IsTrue(string.IsNullOrEmpty(subStatus.Error), $"Error from consumer {deviceType}: {subStatus.Error}"); Assert.IsTrue(subStatus.Subscription.SubscriptionId.HasValue && subStatus.Subscription.SubscriptionId != Guid.Empty, $"No subscriptionid from consumer {deviceType}: {subStatus.Subscription.SubscriptionId}"); } } // TODO verify that subscriptions are actually getting consumed (at least for some consumer plug-ins) { var getSubscriptionsResponse = consumer.GetThingSubscriptionsAsync().Result; Assert.NotNull(getSubscriptionsResponse, $"Timeout or get things message not implemented by consumer {deviceType}"); Assert.IsTrue(string.IsNullOrEmpty(getSubscriptionsResponse.Error), $"Error from consumer {deviceType}: {getSubscriptionsResponse.Error}"); Assert.AreEqual(thingSubscriptions.Count, getSubscriptionsResponse.ThingSubscriptions.Count, $"Missing or too many subscriptions for {deviceType}"); foreach (var sub in getSubscriptionsResponse.ThingSubscriptions) { Assert.IsTrue(sub.SubscriptionId.HasValue && sub.SubscriptionId != Guid.Empty, $"No subscriptionid from consumer {deviceType}: {sub.SubscriptionId}"); } } consumers.Add(consumer); } } var pipelineConfig = sensorThing.GetThingPipelineConfigurationAsync(true).Result; foreach (var thing in consumers) { if (thing.DeviceType != eKnownDeviceTypes.IBaseEngine) { TheThingRegistry.DeleteThing(thing); } } foreach (var thing in providers) { if (thing.DeviceType != eKnownDeviceTypes.IBaseEngine) { TheThingRegistry.DeleteThing(thing); } } // TODO Verify that provider properties are gone TheThingRegistry.DeleteThing(sensorThing); foreach (var thingConfig in pipelineConfig.ThingConfigurations) { if (configs.TryGetValue($"{thingConfig.ThingIdentity.EngineName}/{thingConfig.ThingIdentity.DeviceType}", out var testInfo)) { if (testInfo.SpecializationValues != null) { foreach (var propKV in testInfo.SpecializationValues) { thingConfig.ThingSpecializationParameters[propKV.Key] = propKV.Value; } } } } var owner = TheThingRegistry.GetBaseEngineAsThing(eEngineName.ContentService); var things = TheThing.CreateThingPipelineFromConfigurationAsync(owner, pipelineConfig).Result; Assert.AreEqual(pipelineConfig.ThingConfigurations.Count, things.Count, "Not all pipeline things were created."); Assert.AreEqual(pipelineConfig.ThingConfigurations.Count(cfg => cfg.ThingSpecializationParameters != null), things.Count, "Not all specialization parameters were created."); int i = 0; foreach (var thing in things) { Assert.NotNull(thing, $"Thing {i} not created: {pipelineConfig.ThingConfigurations[i].ThingIdentity}"); i++; } var memoryThing = things.FirstOrDefault(t => t.EngineName == sensorThing.EngineName); Assert.NotNull(memoryThing); var minimumTagCount = configs.Sum(c => c.Value.MinimumBrowseTags); Assert.Greater(memoryThing.MyPropertyBag.Count, minimumTagCount); // TODO adjust this to actual sensors, not just the OPC UA client subscription count foreach (var thing in things) { if (thing.DeviceType != eKnownDeviceTypes.IBaseEngine) { TheThingRegistry.DeleteThing(thing); } } }
public void TestSensorConsumerModel() { var deviceTypes = TheThingRegistry.GetAllDeviceTypesByCap(nsCDEngine.ViewModels.eThingCaps.SensorConsumer, true); Assert.Greater(deviceTypes.Count, 0, "No sensor consumer device types found"); var sensorThing = new TheThing { EngineName = "CDMyVThings.TheVThings", DeviceType = "Memory Tag", ID = "TestSensorThing01" }; TheThingRegistry.RegisterThing(sensorThing); sensorThing.DeclareSensorProperty("Sensor01_1", ePropertyTypes.TNumber, new cdeP.TheSensorMeta { }).Value = 12345.67; sensorThing.DeclareSensorProperty("Sensor01_2", ePropertyTypes.TString, new cdeP.TheSensorMeta { }).Value = "Hello World!"; sensorThing.DeclareSensorProperty("Sensor01_3", ePropertyTypes.TDate, new cdeP.TheSensorMeta { }).Value = DateTimeOffset.Now; var sensorThing2 = new TheThing { EngineName = "CDMyVThings.TheVThings", DeviceType = "Memory Tag", ID = "TestSensorThing02" }; TheThingRegistry.RegisterThing(sensorThing); sensorThing2.DeclareSensorProperty("Sensor02_1", ePropertyTypes.TNumber, new cdeP.TheSensorMeta { }).Value = 12345.67; sensorThing2.DeclareSensorProperty("Sensor02_2", ePropertyTypes.TString, new cdeP.TheSensorMeta { }).Value = "Hello World!"; sensorThing2.DeclareSensorProperty("Sensor02_3", ePropertyTypes.TDate, new cdeP.TheSensorMeta { }).Value = DateTimeOffset.Now; foreach (var deviceType in deviceTypes) { TestInfo testInfo; var consumer = CreateThingForTest(deviceType, out testInfo); WriteLine($"{deviceType}: Consumer created"); var thingSubscriptions = new List <TheThing.TheThingSubscription> { new TheThing.TheThingSubscription { ThingReference = sensorThing, }, new TheThing.TheThingSubscription { ThingReference = sensorThing2, }, }; { var subscribeToThingsResponse = consumer.SubscribeToThingsAsync(thingSubscriptions).Result; Assert.NotNull(subscribeToThingsResponse, $"Timeout or subscribe to things message not implemented by consumer {deviceType}"); Assert.IsTrue(string.IsNullOrEmpty(subscribeToThingsResponse.Error), $"Error from consumer {deviceType}: {subscribeToThingsResponse.Error}"); Assert.GreaterOrEqual(thingSubscriptions.Count, subscribeToThingsResponse.SubscriptionStatus.Count, $"Not enough status reports for {deviceType}"); foreach (var subStatus in subscribeToThingsResponse.SubscriptionStatus) { Assert.IsTrue(string.IsNullOrEmpty(subStatus.Error), $"Error from consumer {deviceType}: {subStatus.Error}"); Assert.IsTrue(subStatus.Subscription.SubscriptionId.HasValue && subStatus.Subscription.SubscriptionId != Guid.Empty, $"No subscriptionid from consumer {deviceType}: {subStatus.Subscription.SubscriptionId}"); } } // TODO verify that subscriptions are actually getting consumed (at least for some consumer plug-ins) { var getSubscriptionsResponse = consumer.GetThingSubscriptionsAsync().Result; Assert.NotNull(getSubscriptionsResponse, $"Timeout or get things message not implemented by consumer {deviceType}"); Assert.IsTrue(string.IsNullOrEmpty(getSubscriptionsResponse.Error), $"Error from consumer {deviceType}: {getSubscriptionsResponse.Error}"); Assert.AreEqual(thingSubscriptions.Count, getSubscriptionsResponse.ThingSubscriptions.Count, $"Missing subscriptions for {deviceType}"); foreach (var sub in getSubscriptionsResponse.ThingSubscriptions) { Assert.IsTrue(sub.SubscriptionId.HasValue && sub.SubscriptionId != Guid.Empty, $"No subscriptionid from consumer {deviceType}: {sub.SubscriptionId}"); } var unsubscribeResponse = consumer.UnsubscribeFromThingsAsync(getSubscriptionsResponse.ThingSubscriptions.Select(sub => sub.SubscriptionId ?? Guid.Empty).Take(1)).Result; Assert.NotNull(unsubscribeResponse, $"Timeout or unsubscribe things message not implemented by consumer {deviceType}"); Assert.IsTrue(string.IsNullOrEmpty(unsubscribeResponse.Error), $"Error from consumer {deviceType}: {unsubscribeResponse.Error}"); Assert.IsTrue(unsubscribeResponse.Failed != null && unsubscribeResponse.Failed.Count == 0, $"Errors during unsubscribe from consumer {deviceType}: {unsubscribeResponse.Failed.Aggregate("", (s, us) => $"{s} {us.Subscription.SubscriptionId}:{us.Error}")}"); } { var getSubscriptionsResponse = consumer.GetThingSubscriptionsAsync().Result; Assert.NotNull(getSubscriptionsResponse, $"Timeout or get things message not implemented by consumer {deviceType}"); Assert.IsTrue(string.IsNullOrEmpty(getSubscriptionsResponse.Error), $"Error from consumer {deviceType}: {getSubscriptionsResponse.Error}"); Assert.AreEqual(thingSubscriptions.Count - 1, getSubscriptionsResponse.ThingSubscriptions.Count, $"Missing subscriptions for {deviceType}"); foreach (var sub in getSubscriptionsResponse.ThingSubscriptions) { Assert.IsTrue(sub.SubscriptionId.HasValue && sub.SubscriptionId != Guid.Empty, $"No subscriptionid from consumer {deviceType}: {sub.SubscriptionId}"); } var unsubscribeResponse = consumer.UnsubscribeFromThingsAsync(getSubscriptionsResponse.ThingSubscriptions.Select(sub => sub.SubscriptionId ?? Guid.Empty)).Result; Assert.NotNull(unsubscribeResponse, $"Timeout or unsubscribe things message not implemented by consumer {deviceType}"); Assert.IsTrue(string.IsNullOrEmpty(unsubscribeResponse.Error), $"Error from consumer {deviceType}: {unsubscribeResponse.Error}"); Assert.IsTrue(unsubscribeResponse.Failed != null && unsubscribeResponse.Failed.Count == 0, $"Errors during unsubscribe from consumer {deviceType}: {unsubscribeResponse.Failed.Aggregate("", (s, us) => $"{s} {us.Subscription.SubscriptionId}:{us.Error}")}"); } { var getSubscriptionsResponse = consumer.GetThingSubscriptionsAsync().Result; Assert.NotNull(getSubscriptionsResponse, $"Timeout or get things message not implemented by consumer {deviceType}"); Assert.IsTrue(string.IsNullOrEmpty(getSubscriptionsResponse.Error), $"Error from consumer {deviceType}: {getSubscriptionsResponse.Error}"); Assert.AreEqual(0, getSubscriptionsResponse.ThingSubscriptions.Count, $"Leaked subscriptions for {deviceType}"); } if (consumer.DeviceType != eKnownDeviceTypes.IBaseEngine) { TheThingRegistry.DeleteThing(consumer); } } TheThingRegistry.DeleteThing(sensorThing); TheThingRegistry.DeleteThing(sensorThing2); }