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); } } }