using MoniteurBaie.DataModels; using MoniteurBaie.Utils; namespace MoniteurBaie.SerialCom; public sealed class MockBatteryController : IBatteryController { private readonly List> _serialObservers = new(); private readonly BlockingListener _commandListener = new(); public Task Open(CancellationToken cancellationToken) { var readThread = new Thread(DoRead) { IsBackground = true }; readThread.Start(); var writeThread = new Thread(DoWrite) { IsBackground = true }; writeThread.Start(); return Task.CompletedTask; } public IDisposable AddSerialObserver(IObserver observer) { _serialObservers.Add(observer); return new Disposer(() => _serialObservers.Remove(observer)); } public Task SendCommand(string command, CancellationToken cancellationToken) { _commandListener.Push(command); return Task.CompletedTask; } private void DoRead() { while (true) { var packet = CreateFakePacket(); foreach (var observer in _serialObservers) { observer.OnNext(packet); } } } private static BatteryControllerPacket CreateFakePacket() { Thread.Sleep(Random.Shared.Next(1000 - 50, 1000 + 50)); return new( DateTime.Now, $"COM,{Random.Shared.NextSingle()},{Random.Shared.NextSingle()},{Random.Shared.NextSingle()},{Random.Shared.NextSingle()},{Random.Shared.NextSingle()},{Random.Shared.NextSingle()},{Random.Shared.NextSingle()},{Random.Shared.NextSingle()},{Random.Shared.NextSingle()},{Random.Shared.NextSingle()},{Random.Shared.NextSingle()},{Random.Shared.NextSingle()},{Random.Shared.NextSingle()},{Random.Shared.NextSingle()},{Random.Shared.NextSingle()},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(100)},{Random.Shared.Next(100)},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(2)},{Random.Shared.Next(2)}"); } private void DoWrite() { try { while (true) { _commandListener.Next(); } } catch (ObjectDisposedException) { } } #region IObservable IDisposable IObservable.Subscribe(IObserver observer) { return AddSerialObserver(observer); } #endregion #region IObserver void IObserver.OnCompleted() { } void IObserver.OnError(Exception error) { } void IObserver.OnNext(string value) { SendCommand(value, default); } #endregion #region IDisposable private bool _disposedValue; private void Dispose(bool disposing) { if (!_disposedValue) { if (disposing) { _commandListener.Dispose(); } _disposedValue = true; } } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } #endregion }