public void ProcessVirtualMessage(InterfaceDatum message) { try { // Test for active first? _rideProcessLock.EnterUpgradeableReadLock(); RideProcessor process = null; _RideProcessors.TryGetValue(message.userId, out process); if (process == null) { process = ActivateUserRider(message.userId); } // Dispatch the message to the rider - this task writes process.AddMessage(message); return; } finally { _rideProcessLock.ExitUpgradeableReadLock(); } }
public Lease[] ProcessMessage(InterfaceDatum[] messages) { try { // Test for active first? _rideProcessLock.EnterReadLock(); List<Lease> unauthorized = new List<Lease>(); foreach (InterfaceDatum message in messages) { RideProcessor process = null; _RideProcessors.TryGetValue(message.userId, out process); if (process != null) { // Check the lease Id if (process.LeaseId == message.ls) { // Dispatch the message to the rider - this task writes process.AddMessage(message); } else { // Lease is not correct unauthorized.Add(new Lease(){ UserId = message.userId, LeaseId = message.ls}); } } else { // User's Ride processor is not available unauthorized.Add(new Lease() { UserId = message.userId, LeaseId = message.ls }); } } return unauthorized.ToArray(); } finally { _rideProcessLock.ExitReadLock(); } }
public void AddMessage(InterfaceDatum message) { try { _queueLock.EnterWriteLock(); // Update the timespamp LastUpdateTimestamp = DateTime.UtcNow; if (_messageQueue.Count < QUEUE_CAPACITY) { _messageQueue.Enqueue(message); } } finally { _queueLock.ExitWriteLock(); } // Now process the queue try { _queueLock.EnterReadLock(); while (_messageQueue.Count > 0) { InterfaceDatum p = _messageQueue.Dequeue(); ProcessMessage(p); } } finally { _queueLock.ExitReadLock(); } try { _outputLock.EnterReadLock(); CycliManager.Instance.SendSpotData(UserId, _spotData); } finally { _outputLock.ExitReadLock(); } }
private void ProcessMessage(InterfaceDatum p) { try { if (_outputLock.TryEnterWriteLock(OUTPUT_LOCK_TIMEOUT_MS)) { if (_lastMessage != null) { _lastSpotData = _spotData.Copy(); _spotData.id = UserId; _spotData.t = Utilities.DbTime.ToUnsignedDbTicks(DateTime.UtcNow); // heartrate is easy - just check its not a reset _spotData.h = p.h; // Speed if (p.wt > 0) { double deltaDistance = 0.000001 * (double)p.w * (double)_Rider.BikeWheelSizeMm * Math.PI; _spotData.s = (float)(deltaDistance * 1024 * 3600 / (double)p.wt); // kmph } // Cadence if (p.pt > 0) { _spotData.c = (int)(60 * 1024 * (double)p.p / (double)p.pt); } // Power if (_Rider.EstimatedPower && _Turbo == null) { _spotData.p = 0; } // This condition will only estimate if we're not calibrating else if (_Rider.EstimatedPower && _calibrationTimer == null) { _spotData.p = (int)_Turbo.Power(_spotData.s); } else { if (p.ec > 0) { _spotData.p = (int)((float)p.e / (float)p.ec); if (_lastSpotData != null) { // Take a time average double dt = 0.001 * (double)(_spotData.t - _lastSpotData.t); float sf = (float)Math.Exp(-dt / 1.7); _spotData.p = (int)(sf * _lastSpotData.p + (1 - sf) * _spotData.p); } } else { _spotData.p = 0; } } // Are we calibrating - this if (_calibrationTimer != null) { _Turbo.UpdateCalibrationData(this, _spotData); string message = _Turbo.GetCalibrationMessage(); if (!string.IsNullOrEmpty(message)) { CycliManager.Instance.SendCalibrationMessage(UserId, message); } } } _lastMessage = p; } } catch (Exception ex) { Debug.WriteLine(ex.Message); } finally { _outputLock.ExitWriteLock(); } // Let the outside world know - this is outside the lock as // the race processor will try and access the updated data // within a read lock System.Diagnostics.Debug.WriteLine(string.Format("Ride Process:{0} {1} {2:N2} {3:N2}", _spotData.id, _spotData.t, _spotData.s, _spotData.p)); OnSpotData(); }
private InterfaceDatum GetMessage(double p) { InterfaceDatum _message = new InterfaceDatum(); // Get the estimated speed in km/hr and convert to millimetres per second double s = 1000 * KMPH_TO_MPS * TurboTrainer.PowerNormalisedSpeed(p); // How long will this take to rotate once in 1024 ticks per second ushort wt = 65535; if(s > 0) { double t = 1024 * Math.PI * this.BikeWheelSizeMm / s; if (t <= 65535) { wt = (ushort)Math.Floor(t); } } _message.userId = this.UserId; _message.h = 90; _message.ht = 1024; _message.w = 1; _message.wt = wt; _message.p = 1; _message.pt = 750; //1024 = 1 second _message.e = (ushort)p; _message.ec = 1; if (_messageCounter == ushort.MaxValue) { _messageCounter = 0; } else { _messageCounter++; } return _message; }