/// <inheritdoc/> public async Task HandleDeviceTwinEventAsync(DeviceTwinEvent ev) { if (ev.Handled) { return; } if (string.IsNullOrEmpty(ev.Twin.Id) || string.IsNullOrEmpty(ev.Twin.ModuleId)) { return; } var type = ev.Twin.Properties?.Reported.GetValueOrDefault <string>( TwinProperty.Type, null); if ((ev.Event != DeviceTwinEventType.Delete && ev.IsPatch) || string.IsNullOrEmpty(type)) { try { ev.Twin = await _iothub.GetAsync(ev.Twin.Id, ev.Twin.ModuleId); ev.IsPatch = false; type = ev.Twin.Properties?.Reported?.GetValueOrDefault <string>( TwinProperty.Type, null); } catch (Exception ex) { _logger.Verbose(ex, "Failed to materialize twin"); } } if (IdentityType.Discoverer.EqualsIgnoreCase(type)) { var ctx = new RegistryOperationContextModel { AuthorityId = ev.AuthorityId, Time = ev.Timestamp }; switch (ev.Event) { case DeviceTwinEventType.New: break; case DeviceTwinEventType.Create: await _broker.NotifyAllAsync(l => l.OnDiscovererNewAsync(ctx, ev.Twin.ToDiscovererRegistration(false).ToServiceModel())); break; case DeviceTwinEventType.Update: await _broker.NotifyAllAsync(l => l.OnDiscovererUpdatedAsync(ctx, ev.Twin.ToDiscovererRegistration(false).ToServiceModel())); break; case DeviceTwinEventType.Delete: await _broker.NotifyAllAsync(l => l.OnDiscovererDeletedAsync(ctx, DiscovererModelEx.CreateDiscovererId( ev.Twin.Id, ev.Twin.ModuleId))); break; } ev.Handled = true; } }
/// <inheritdoc/> public async Task HandleDeviceTwinEventAsync(DeviceTwinEvent ev) { if (ev.Handled) { return; } if (string.IsNullOrEmpty(ev.Twin.Id)) { return; } var type = ev.Twin.Tags.GetValueOrDefault <string>( nameof(EntityRegistration.DeviceType), null); if ((ev.Event != DeviceTwinEventType.Delete && ev.IsPatch) || string.IsNullOrEmpty(type)) { try { ev.Twin = await _iothub.GetAsync(ev.Twin.Id); ev.IsPatch = false; type = ev.Twin.Tags.GetValueOrDefault <string>( nameof(EntityRegistration.DeviceType), null); } catch (Exception ex) { _logger.Verbose(ex, "Failed to materialize twin"); } } if (IdentityType.Endpoint.EqualsIgnoreCase(type)) { var ctx = new RegistryOperationContextModel { AuthorityId = ev.AuthorityId, Time = ev.Timestamp }; switch (ev.Event) { case DeviceTwinEventType.New: break; case DeviceTwinEventType.Create: await _broker.NotifyAllAsync(l => l.OnEndpointNewAsync(ctx, ev.Twin.ToEndpointRegistration(false).ToServiceModel())); break; case DeviceTwinEventType.Update: await _broker.NotifyAllAsync(l => l.OnEndpointUpdatedAsync(ctx, ev.Twin.ToEndpointRegistration(false).ToServiceModel())); break; case DeviceTwinEventType.Delete: await _broker.NotifyAllAsync(l => l.OnEndpointDeletedAsync(ctx, ev.Twin.Id, ev.Twin.ToEndpointRegistration(false).ToServiceModel())); break; } ev.Handled = true; } }
/// <inheritdoc/> public async Task HandleAsync(string deviceId, string moduleId, byte[] payload, IDictionary <string, string> properties, Func <Task> checkpoint) { if (_handlers.Count == 0) { return; } if (!properties.TryGetValue("opType", out var opType) || !properties.TryGetValue("operationTimestamp", out var ts)) { return; } DateTime.TryParse(ts, out var timestamp); if (timestamp + TimeSpan.FromSeconds(10) < DateTime.UtcNow) { // Drop twin events that are too far in our past. _logger.Debug("Skipping {event} from {deviceId}({moduleId}) from {ts}.", opType, deviceId, moduleId, timestamp); return; } var twin = Try.Op(() => _serializer.Deserialize <DeviceTwinModel>(payload)); if (twin == null) { return; } twin.ModuleId = moduleId; twin.Id = deviceId; var operation = GetOperation(opType); if (operation == null) { return; } var ev = new DeviceTwinEvent { Twin = twin, Event = operation.Value, IsPatch = true, Handled = false, AuthorityId = null, // TODO Timestamp = timestamp }; foreach (var handler in _handlers) { await handler.HandleDeviceTwinEventAsync(ev); } }
/// <summary> /// IoTHubによるデバイスツイン更新EventDataを変換する /// </summary> /// <param name="eventData">EventData</param> /// <returns>RmsEvent</returns> /// <remarks> /// - EventDataがnullの場合はArgumentNullExceptionを投げる /// - EventData#Bodyをデシリアライズできない場合ArgumentExceptionを投げる /// - EdgeIDをSystemPropertiesから取得できない場合はFormatExceptionを投げる /// </remarks> private RmsEvent ConvertTwinChanged(EventData eventData) { // Body以下に必要な情報が格納されている string body = Encoding.UTF8.GetString(eventData.Body.Array, eventData.Body.Offset, eventData.Body.Count); // Bodyをデシリアライズして必要な情報を抽出 DeviceTwinEvent deviceTwinEvent = DeviceTwinEvent.DeserializeIfInvalidThrowEx(body); return(new RmsEvent() { //// EdgeIDを取得 EdgeId = DeviceTwinEvent.GetEdgeId(eventData), //// MessageId //// MessageDataTime /// 他のDispatcherと合わせるため、この時点ではBodyは文字列にしておく。 MessageBody = JsonConvert.SerializeObject(deviceTwinEvent.Reported) }); }