public override List <T1> ReadJson(JsonReader reader, Type objectType, List <T1> existingValue, bool hasExistingValue, JsonSerializer serializer) { var list = new List <T1>(); var jObject = JObject.Load(reader); foreach (var jToken in jObject.Values()) { Enum.TryParse(jToken[_typeDefiningProperty].Value <string>(), out T2 typedEnum); var raw = jToken.ToString(); try { var type = EnumToType.GetType(typedEnum, raw); if (JsonConvert.DeserializeObject(raw, type) is T1 typedItem) { typedItem.RawJson = raw; list.Add(typedItem); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"Error parsing following type {typedEnum.ToString()}, json: {raw}"); throw ex; } } return(list); }
public IObservable <EventNotification> ReceiveEvents(CancellationToken cancellationToken = default) { if (Interlocked.CompareExchange(ref _receiveEventsIsEntered, 1, 0) != 0) { return(_subject); } if (_webSocketReceiveTask == null || _webSocketReceiveTask.IsCompleted) { var buffer = new byte[1024]; var list = new List <byte>(); _webSocketReceiveTask = Task.Run(async() => { await _clientWebSocket.ConnectAsync(new Uri(UrlWebSocket), cancellationToken); while (_clientWebSocket.State == WebSocketState.Open) { if (cancellationToken.IsCancellationRequested) { await _clientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None); _subject.OnCompleted(); break; } try { var result = await _clientWebSocket.ReceiveAsync(new ArraySegment <byte>(buffer), cancellationToken); switch (result.MessageType) { case WebSocketMessageType.Text: break; case WebSocketMessageType.Binary: list.AddRange(buffer.Take(result.Count)); if (result.EndOfMessage) { var msgString = Encoding.UTF8.GetString(list.ToArray()); _logger?.LogDebug($"Message received: {msgString}"); var msg = JsonConvert.DeserializeObject <JObject>(msgString); foreach (var hEvent in msg["events"].Values()) { Enum.TryParse(hEvent["pushEventType"].Value <string>(), out EventType eventType); HomematicIpObjectBase homematicIpObjectBase = null; switch (eventType) { case EventType.SECURITY_JOURNAL_CHANGED: break; case EventType.GROUP_ADDED: case EventType.GROUP_CHANGED: case EventType.GROUP_REMOVED: Enum.TryParse(hEvent["group"]["type"].Value <string>(), out GroupType groupType); var rawGroup = hEvent["group"].ToString(); var type = EnumToType.GetType(groupType, rawGroup); var typedGroup = JsonConvert.DeserializeObject(rawGroup, type); homematicIpObjectBase = typedGroup as HomematicIpObjectBase; if (homematicIpObjectBase != null) { homematicIpObjectBase.RawJson = rawGroup; } break; case EventType.DEVICE_REMOVED: case EventType.DEVICE_CHANGED: case EventType.DEVICE_ADDED: Enum.TryParse(hEvent["device"]["type"].Value <string>(), out DeviceType deviceType); var rawDevice = hEvent["device"].ToString(); var dType = EnumToType.GetType(deviceType, rawDevice); var typedDevice = JsonConvert.DeserializeObject(rawDevice, dType); homematicIpObjectBase = typedDevice as HomematicIpObjectBase; if (homematicIpObjectBase != null) { homematicIpObjectBase.RawJson = rawDevice; } break; case EventType.CLIENT_REMOVED: case EventType.CLIENT_CHANGED: case EventType.CLIENT_ADDED: break; case EventType.HOME_CHANGED: var rawHome = hEvent["home"].ToString(); homematicIpObjectBase = JsonConvert.DeserializeObject <Home>(rawHome); homematicIpObjectBase.RawJson = rawHome; break; case EventType.INCLUSION_REQUESTED: Enum.TryParse(hEvent["deviceType"].Value <string>(), out DeviceType deviceTypeRequested); Enum.TryParse(hEvent["errorReason"].Value <string>(), out ErrorReasonType errorReasonType); var deviceId = hEvent["deviceId"].Value <string>(); homematicIpObjectBase = new Device { Id = deviceId, DeviceType = deviceTypeRequested }; break; default: throw new ArgumentOutOfRangeException(); } if (homematicIpObjectBase != null) { _subject.OnNext(new EventNotification { EventType = eventType, HomematicIpObjectBase = homematicIpObjectBase }); } } list.Clear(); } break; case WebSocketMessageType.Close: await _clientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, cancellationToken); _subject.OnCompleted(); break; default: throw new ArgumentOutOfRangeException(); } } catch (TaskCanceledException) { if (!cancellationToken.IsCancellationRequested) { throw; } } } }); } _receiveEventsIsEntered = 0; return(_subject); }