public void ChangeRateState(RateState state) { if (state == State) { return; } { State = state; } }
public async Task GetEthRate() { var getRateAction = new GetRateAction { FromCurrency = "ETH", ToCurrency = "USD" }; _ = await Mediator.Send(getRateAction); RateState result = Store.GetState <RateState>(); result.ShouldNotBe(null); Console.WriteLine("{ result.Rate}"); }
protected override async Task OnAfterRenderAsync(bool aFirstRender) { Conversion?conversion = RateState.GetConversion(CurrencyCode, ShortFiatCurrencyCode); if (conversion == null || conversion.TimeStamp.AddMinutes(5) < DateTime.UtcNow) { var getRateAction = new GetRateAction { ToCurrency = ShortFiatCurrencyCode, FromCurrency = CurrencyCode }; _ = await Mediator.Send(getRateAction); } }
//public GetRateAction GetRateAction { get; set; } public async Task GetAgldRate() { var getRateAction = new GetRateAction { FromCurrency = "AGLD", ToCurrency = "USD" }; _ = await Mediator.Send(getRateAction); RateState result = Store.GetState <RateState>(); result.ShouldNotBe(null); result.Conversions.Count.ShouldBeGreaterThan(0); RateState.Conversion conversion = result.GetConversion("AGLD", "USD"); conversion.ShouldNotBeNull(); // TODO add more asserts }
// 计算心率 protected virtual bool CalcRate() { int allSize = HeartContext.AdjustSec*HeartContext.F; if (ecgQueue.Count >= allSize) { var ecgList = ecgQueue.ToList(); List<int> posR = new List<int>(); // R值位置 int i = 1; for (i = 1; i < ecgList.Count; i++) { double delta = ecgList[i] - ecgList[i - 1]; delta = Math.Abs(delta); if(delta > D1) { i++; if (i >= ecgQueue.Count) break; delta = ecgList[i] - ecgList[i - 1]; delta = Math.Abs(delta); if(delta > D2) { i++; if (i >= ecgQueue.Count) break; int endIndex = i+(int)(0.1 * HeartContext.F); endIndex = endIndex >= ecgList.Count?ecgList.Count:endIndex; for (; i < endIndex; i++) { delta = ecgList[i] - ecgList[i - 1]; if(Math.Abs(delta) > D3 && delta < 0) // 找到R波点 { // 确定R波位置和RR间期 int r = i - 1; posR.Add(r); int newRR = posR.Last() - LastRIndex; if (newRR >= 0.6*RR && newRR <= 1.6 * RR) { RR = (int)((RR + newRR) / 2); // 更新阈值 DList = DList.OrderByDescending(e => e).ToList(); DList[DList.Count - 1] = delta; double n0 = DList.Average(); D1 = 0.25*n0+0.1*D1; D2 = 0.2*n0+0.2*D1; D3 = 0.1*n0+0.1*D1; } else if (newRR < 0.6 * RR) // 检测多检,论文没有说明,暂时留空 { } else if (newRR > 1.6 * RR) // 检测漏检,包括倒置R波 { int pr = LastRIndex < 0 ? 0 : LastRIndex; int start = pr + (int)(0.7 * RR); int end = pr + (int)(1.2 * RR); if (end - start <= 0) // 没有序列 break; // 此范围内找幅值最大的点 var tempList = ecgList.Skip(start).Take(end - start).ToList(); var maxHR = ecgList.Max(); if (maxHR > 0.8 * HR && maxHR < 1.2 * RR) { var maxIndex = tempList.IndexOf(maxHR); i = maxIndex; r = i + 1; posR.Add(r); newRR = posR.Last() - LastRIndex; RR = (int)((RR + newRR) / 2); } else // 如果幅值最大点不满足,则找幅值最小点 { var minIndex = tempList.IndexOf(tempList.Min()); i = minIndex; r = i + 1; posR.Add(r); newRR = posR.Last() - LastRIndex; RR = (int)((RR + newRR) / 2); } } LastRIndex = i; // 更新 i += (int)(0.1 * HeartContext.F); } } } } } double rr = 0; if (posR.Count == 0) { NewRate = null; } if (posR.Count == 1 && RR > 0) { rr = 60 * HeartContext.F / RR; NewRate = Convert.ToInt32(rr); } else if (posR.Count > 1) { if (posR.Last() - posR.First() == 0) NewRate = null; else { rr = 60 * HeartContext.F * (posR.Count - 1) / (double)(posR.Last() - posR.First()); NewRate = Convert.ToInt32(rr); } } LastRIndex -= ecgList.Count; ecgList.Clear(); ecgQueue.Clear(); return true; } State = RateState.Initialized; return false; }
public override void Stop() { base.Stop(); Clear(); State = RateState.Jumped; }
// 跳过前3秒的混乱数据 private void Jump() { if(ecgQueue.Count >= HeartContext.JumpSec * HeartContext.F) { Clear(); State = RateState.Uninitialized; } }
// 清空参数 private void Clear() { ecgQueue.Clear(); D1 = 0.0; D2 = 0.0; D3 = 0.0; ErrorCnt = 0; LastRate = -1; NewRate = null; State = RateState.Jumped; }
// 检测错误次数 private void CheckError() { if (ErrorCnt >= 2 || WarningCnt >= 5) { State = RateState.Error; ErrorCnt = 0; WarningCnt = 0; } }
// 初始化阈值 protected virtual void InitThesold() { int allSize = HeartContext.ThesoldSec * HeartContext.F; if (ecgQueue.Count >= allSize) { var ecgList = ecgQueue.ToList(); var diffList = Diff(ecgList); int size = HeartContext.ThesoldSec * HeartContext.F / HeartContext.ThesoldSec; double[] ddThesold = new double[HeartContext.ThesoldSec]; for (int i = 0; i < HeartContext.ThesoldSec; i++) { var sequence = diffList.Skip(i * size).Take(size); ddThesold[i] = diffList.Max(); } // 确定初始阈值 DList.AddRange(ddThesold); // 去除一个最高值和一个最低值,再取平均 DList = DList.OrderByDescending(e => e).ToList(); DList.RemoveAt(DList.Count - 1); // 去除最低值 DList.RemoveAt(0); // 去除最高值 double m0 = DList.Average(); D1 = m0 * 0.4; D2 = m0 * 0.5; D3 = m0 * 2.0 / 9; List<int> posR = new List<int>(); // R值位置 for (int i = 1; i < ecgList.Count; i++) { double delta = ecgList[i] - ecgList[i - 1]; delta = Math.Abs(delta); if (delta > D1) { i++; if (i >= ecgQueue.Count) break; delta = ecgList[i] - ecgList[i - 1]; delta = Math.Abs(delta); if (delta > D2) { i++; if (i >= ecgQueue.Count) break; int endIndex = i + (int)(0.1 * HeartContext.F); endIndex = endIndex >= ecgList.Count ? ecgList.Count : endIndex; for (; i < endIndex; i++) { delta = ecgList[i] - ecgList[i - 1]; if (Math.Abs(delta) > D3 && delta < 0) // 找到R波点 { // 确定R波位置和RR间期 int r = i - 1; posR.Add(r); i += (int)(0.1 * HeartContext.F); } } } } } // 确定RR间期和R波幅度 posR = posR.Take(10).ToList(); if (posR.Count > 1) { for (int i = 1; i < posR.Count; i++) { RR += posR[i] - posR[i - 1]; HR += ecgList[posR[i]]; } RR /= (posR.Count - 1); RR *= 1.1; HR /= (posR.Count - 1); LastRIndex = posR.Last() - ecgList.Count; State = RateState.Initialized; } else // 如果RR间期无法确定,重新计算阈值 { State = RateState.Uninitialized; Console.WriteLine("重新计算阈值"); } diffList.Clear(); ecgList.Clear(); ecgQueue.Clear(); } }