public override async Task UpdateObjectAsync(KeyValuePair <string, object> kvp) { Log.WriteLine("\t\t\t\t\t\tI2C UpdateObjectAsync override kvp = {0}", kvp.ToString()); if (kvp.Key == Keys.Orientation) { // output the event stream var msgvalue = new OrientationMessage(); msgvalue.OriginalEventUTCTime = DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Utc).ToString("o"); msgvalue.OrientationState = (Orientation)kvp.Value; byte[] msgbody = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(msgvalue)); lock (_lastOBody) { _lastOBody = msgbody; } await Task.WhenAll( Task.Run(async() => { await Module.SendMessageAsync(Keys.OutputOrientation, msgbody); } ), Task.Run(async() => { await Module.SendMessageAsync(Keys.OutputUpstream, msgbody); } ) ); Log.WriteLine("\t\t\t\t\t\tI2C UpdateObjectAsync orientation sent local and upstream"); } }
private async Task ProcessOrientationMessage(OrientationMessage orientationMsg) { DateTime originalEventUTC = DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Utc); if (orientationMsg.OriginalEventUTCTime != null) { originalEventUTC = DateTime.Parse(orientationMsg.OriginalEventUTCTime, null, System.Globalization.DateTimeStyles.RoundtripKind); } lock (OrientationChanged) { if (originalEventUTC >= _lastOrientationUTC) { Log.WriteLine("OrientationMsgHandler invoking event. original event UTC {0} prev {1}", originalEventUTC.ToString("o"), _lastOrientationUTC.ToString("o")); OrientationChanged?.Invoke(this, orientationMsg.OrientationState); _lastOrientationUTC = originalEventUTC; } else { Log.WriteLine("OrientationMsgHandler ignoring stale message. original event UTC {0} prev {1}", originalEventUTC.ToString("o"), _lastOrientationUTC.ToString("o")); } } await Task.CompletedTask; return; }
public static async Task C2DOrientationMessage(string connectionString, string destDeviceId, string destModule, Orientation oState, string EventMsgTime, ILogger log) { ServiceClient client = ServiceClient.CreateFromConnectionString(connectionString); log.LogInformation("have service client"); OrientationMessage oMsg = new OrientationMessage(); oMsg.OrientationState = oState; oMsg.OriginalEventUTCTime = EventMsgTime; var mi = new CloudToDeviceMethod(Keys.SetOrientation); mi.ConnectionTimeout = TimeSpan.FromSeconds(DEFAULT_NETWORK_TIMEOUT); mi.ResponseTimeout = TimeSpan.FromSeconds(DEFAULT_NETWORK_TIMEOUT); mi.SetPayloadJson(JsonConvert.SerializeObject(oMsg)); // Invoke the direct method asynchronously and get the response from the simulated device. log.LogInformation("invoking device method for {0} {1} with {2} json {3}", destDeviceId, destModule, mi.MethodName, mi.GetPayloadAsJson()); var r = await client.InvokeDeviceMethodAsync(destDeviceId, destModule, mi); log.LogInformation("device method invocation complete"); return; }
public override async Task UpdateObjectAsync(KeyValuePair <string, object> kvp) { Log.WriteLine("\t\t\t\t\t\tSPI UpdateObjectAsync override kvp = {0}", kvp.ToString()); if (kvp.Key == Keys.Orientation) { // output the event stream var msgvalue = new OrientationMessage(); msgvalue.OriginalEventUTCTime = DateTime.UtcNow.ToString("o"); msgvalue.OrientationState = (Orientation)kvp.Value; byte[] msgbody = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(msgvalue)); lock (_lastOBody) { _lastOBody = msgbody; } await Task.WhenAll( Task.Run(async() => { try { await Module.SendMessageAsync(Keys.OutputOrientation, msgbody); } catch (Exception e) { Log.WriteLineError("SPI Exception updating orientation local {0}", e.ToString()); } }), Task.Run(async() => { try { var m = new Message(msgbody); await Module.SendMessageAsync(Keys.OutputUpstream, msgbody); } catch (Exception e) { Log.WriteLineError("SPI Exception updating orientation upstream {0}", e.ToString()); } }) ); } }
public static async Task HubRun([IoTHubTrigger("messages/events", Connection = "EndpointConnectionString")] EventData message, ILogger log, WebJobsExecutionContext context) { try { string msg = Encoding.UTF8.GetString(message.Body); log.LogInformation("{0} C# IoT Hub trigger function received a message: {1} ::: {2}", Thread.CurrentThread.ManagedThreadId, Dump(message), message.ToString()); log.LogInformation($"payload: {msg}"); if (message.SystemProperties == null) { log.LogInformation("no system metadata. unable to determine source device -- ignoring"); return; } if (message.Properties != null && message.Properties.ContainsKey(Keys.iothubMessageSchema) && (string)message.Properties[Keys.iothubMessageSchema] == Keys.twinChangeNotification) { log.LogInformation("twin notification -- ignoring"); return; } string sourceDeviceId = (string)message.SystemProperties[Keys.DeviceIdMetadata]; string sourceModuleId = (string)message.SystemProperties[Keys.ModuleIdMetadata]; log.LogInformation($"Have device id {sourceDeviceId}"); var config = new ConfigurationBuilder().SetBasePath(context.FunctionAppDirectory).AddJsonFile("local.settings.json", optional: true, reloadOnChange: true).AddEnvironmentVariables().Build(); string conn = config[Keys.HubConnectionString]; log.LogInformation("Have connection string {0}", conn); var rm = RegistryManager.CreateFromConnectionString(conn); log.LogInformation("Have registry manager"); var destDevices = await GetDestinationDevices(sourceDeviceId, rm, log); log.LogInformation("Have topology"); ModuleLoadedMessage loadMsg = JsonConvert.DeserializeObject <ModuleLoadedMessage>(msg); if ((loadMsg != null) && (loadMsg.ModuleName != null) && (loadMsg.ModuleName.Length > 0)) { if (sourceModuleId != loadMsg.ModuleName) { log.LogError("ignoring message because metadata inconsistency. system property moduleId = {0} message module {1}", sourceModuleId, loadMsg.ModuleName); return; } log.LogInformation("Load Module {0}", loadMsg.ModuleName); var destModulesFromRouteList = LoadMsgRouting.Where(routeSourceModuleEntry => routeSourceModuleEntry.Item1 == sourceModuleId); int destModulesFromRouteSize = destModulesFromRouteList.Count(); if (destModulesFromRouteSize == 0) { log.LogInformation("no destination routes for module {0} -- ignoring", sourceModuleId); return; } if (destModulesFromRouteSize > 1) { log.LogError("configuration error. found {0} route destination lists. expected at most 1.", destModulesFromRouteSize); return; } var destModulesFromRoute = destModulesFromRouteList.First().Item2; foreach (var destDeviceId in destDevices) { log.LogInformation("examining destination device {0}", destDeviceId); List <string> destCandidateNames = await GetDeviceModulesAsync(destDeviceId, rm, log); var destModules = destCandidateNames.Where(n => n != sourceModuleId).Intersect(destModulesFromRoute, StringComparer.InvariantCulture); log.LogInformation("sending loadmsg to destination {0} modules", destModules.Count()); foreach (var destModule in destModules) { try { log.LogInformation("sending loadmsg to destination module {0} on {1}", destModule, destDeviceId); await C2DModuleMessage(conn, destDeviceId, destModule, sourceModuleId, log); } catch (Exception e) { log.LogInformation("{0} exception sending module load of {0} to device {1} module {2}", e.ToString(), sourceModuleId, destDeviceId, destModule); } } } return; } log.LogInformation("Not a Load Module -- checking for fruit"); FruitMessage fruitMsg = JsonConvert.DeserializeObject <FruitMessage>(msg); if (fruitMsg.FruitSeen != null && fruitMsg.FruitSeen.Length > 0) { log.LogInformation("fruit msg original time {0} fruit {1}", fruitMsg.OriginalEventUTCTime, fruitMsg.FruitSeen); //log.LogInformation("found {0} slave devices", slaves.Length); string originaleventtime = fruitMsg.OriginalEventUTCTime; if (originaleventtime == null && message.Properties.ContainsKey(Keys.MessageCreationUTC)) { originaleventtime = (string)message.Properties[Keys.MessageCreationUTC]; } var destModulesFromRouteList = FruitMsgRouting.Where(routeSourceModuleEntry => routeSourceModuleEntry.Item1 == sourceModuleId); int destModulesFromRouteSize = destModulesFromRouteList.Count(); if (destModulesFromRouteSize == 0) { log.LogInformation("no destination routes for module {0} -- ignoring", sourceModuleId); return; } if (destModulesFromRouteSize > 1) { log.LogError("configuration error. found {0} route destination lists. expected at most 1.", destModulesFromRouteSize); return; } var destModulesFromRoute = destModulesFromRouteList.First().Item2; log.LogInformation("{0} destination modules for route", destModulesFromRoute.Count()); foreach (var destDeviceId in destDevices) { log.LogInformation("examining destination device {0}", destDeviceId); List <string> destCandidateNames = await GetDeviceModulesAsync(destDeviceId, rm, log); log.LogInformation("interecting {0} destmodules with {1} routemodules", destCandidateNames.Count(), destModulesFromRoute.Length); var destModules = destCandidateNames.Intersect(destModulesFromRoute, StringComparer.InvariantCulture); log.LogInformation("{0} modules after intersection", destModules.Count()); if (destModules == null || destModules.Count() == 0) { log.LogInformation("destination modules and routes list have empty intersection"); } foreach (var destModule in destModules) { try { log.LogInformation("sending fruitmsg to destination module {0} on {1}", destModule, destDeviceId); await C2DFruitMessage(conn, destDeviceId, destModule, fruitMsg.FruitSeen, originaleventtime, log); } catch (Exception e) { log.LogInformation("{0} exception sending module load of {0} to device {1} module {2}", e.ToString(), sourceModuleId, destDeviceId, destModule); } } } return; } log.LogInformation("Not a fruit message -- checking for orientation"); OrientationMessage oMsg = JsonConvert.DeserializeObject <OrientationMessage>(msg); if (oMsg.OrientationState != Orientation.Unknown) { log.LogInformation("orientation msg original time {0} orientation {1} sourceDeviceId {2} sourceModuleId {3}", oMsg.OriginalEventUTCTime, oMsg.OrientationState, sourceDeviceId, sourceModuleId); //log.LogInformation("found {0} slave devices", slaves.Length); string originaleventtime = oMsg.OriginalEventUTCTime; if (originaleventtime == null && message.Properties.ContainsKey(Keys.MessageCreationUTC)) { originaleventtime = (string)message.Properties[Keys.MessageCreationUTC]; } var destModulesFromRouteList = OrientationMsgRouting.Where(routeSourceModuleEntry => routeSourceModuleEntry.Item1 == sourceModuleId); int destModulesFromRouteSize = destModulesFromRouteList.Count(); if (destModulesFromRouteSize == 0) { log.LogInformation("no destination routes for module {0} -- ignoring", sourceModuleId); return; } if (destModulesFromRouteSize > 1) { log.LogError("configuration error. found {0} route destination lists. expected at most 1.", destModulesFromRouteSize); return; } log.LogInformation("orientation msg 1 route list as expected. examining {0} dest devices", destDevices.Count()); var destModulesFromRoute = destModulesFromRouteList.First().Item2; foreach (var destDeviceId in destDevices) { log.LogInformation("examining destination device {0}", destDeviceId); List <string> destCandidateNames = await GetDeviceModulesAsync(destDeviceId, rm, log); var destModules = destCandidateNames.Where(n => n != sourceModuleId).Intersect(destModulesFromRoute, StringComparer.InvariantCulture); log.LogInformation("sending loadmsg to destination {0} modules", destModules.Count()); foreach (var destModule in destModules) { try { log.LogInformation("sending orientation msg to destination module {0} on {1}", destModule, destDeviceId); await C2DOrientationMessage(conn, destDeviceId, destModule, oMsg.OrientationState, originaleventtime, log); } catch (Exception e) { log.LogInformation("{0} exception sending module load of {0} to device {1} module {2}", e.ToString(), sourceModuleId, destDeviceId, destModule); } } } return; } } catch (Exception e) { log.LogInformation("{0} HubRun failed with exception {1}", Thread.CurrentThread.ManagedThreadId, e.ToString()); } log.LogInformation("{0}HubRun complete", Thread.CurrentThread.ManagedThreadId); return; }