protected virtual void RaiseObisDataEvent(ObisData data) { // Raise the event in a thread-safe manner using the ?. operator. ObisDataEvent?.Invoke(this, new ObisDataEventArgs(data.Raw, data.Code, data.Value, data.Unit)); }
private async Task <bool> ReadObisMessageAsync() { var code = new StringBuilder(); var value = new StringBuilder(); var unit = new StringBuilder(); var raw = new StringBuilder(); var obisdata = new List <ObisData>(); var state = ParseState.OBIS_BLOCK_START; while (!_token.IsCancellationRequested && (state != ParseState.STOPPARSING)) { var data = await _reader.ReadByteAsync(); _hexDump.DumpByte(HexDumpMode.BytesIn, data); switch (state) { case ParseState.OBIS_BLOCK_START: if (data == Constants.FrameStart) { state = ParseState.OBIS_CODE; } break; case ParseState.OBIS_CODE: if (data == Constants.EndMessage) { state = ParseState.OBIS_BLOCK_END; break; } if ((char)data == '(') { raw.Append((char)data); state = ParseState.OBIS_VALUE; break; } if (code.Length < Constants.ObisCodeMaxLength) { raw.Append((char)data); code.Append((char)data); } else { throw new Exception(); } break; case ParseState.OBIS_VALUE: if ((char)data == '*') { raw.Append((char)data); state = ParseState.OBIS_UNIT; break; } if ((char)data == ')') { raw.Append((char)data); state = ParseState.OBIS_ITEM_END; break; } if (value.Length < Constants.ObisValueMaxLength) { raw.Append((char)data); value.Append((char)data); } else { throw new Exception(); } break; case ParseState.OBIS_UNIT: if ((char)data == ')') { raw.Append((char)data); state = ParseState.OBIS_ITEM_END; break; } if (unit.Length < Constants.ObisUnitMaxLength) { raw.Append((char)data); unit.Append((char)data); } else { throw new Exception(); } break; case ParseState.OBIS_ITEM_END: if (data == Constants.CR) { continue; } if (data == Constants.LF) { var item = new ObisData(raw.ToString(), code.ToString(), value.ToString(), unit.ToString()); obisdata.Add(item); RaiseObisDataEvent(item); raw.Clear(); code.Clear(); value.Clear(); unit.Clear(); state = ParseState.OBIS_CODE; break; } break; case ParseState.OBIS_BLOCK_END: if (data == Constants.CR || data == Constants.LF) { continue; } if (data == Constants.FrameEnd) { state = ParseState.STOPPARSING; break; } throw new Exception(); // unexpected character default: break; } } return(true); }