/// <summary>Показание счетчика с момента запуска</summary> /*private OperationResult TryReadEnergyFromLaunch(IIODriverClient channel, ShortRequest request, out Energy response) * { * return TryReadEnergy(channel, request, Codes.CODE_TOTAL, 0, 0, 0, out response); * }*/ #endregion #region Энергия по времени /// <summary>Чтение 30 минутных срезов энергии</summary> /// <param name="channel">Канал</param> /// <param name="request">Запрос</param> /// <param name="timeSlices">Время среза должно быть точное и выравненне</param> public OperationResult TryReadSlicesEnergy(IIODriverClient channel, string psw, DeviceCompOn deviceTime, SlicesQuery request, out Energy response) { response = Energy.Default; //log.Trace.Write(1, (l) => l.Info("Emul: {0}", request.EmulError)); if (!request.EmulError) { //log.Trace.Write(1, (l) => l.Info("DiffMsec: {0}, DiffMsecReal: {1}, DeviceTimeUtc: {2}, IsTimeSlices: {3}, TimeOneSidePathMsec: {4}, TimeSlices: {5}", // deviceTime.DiffMsec, deviceTime.DiffMsecReal, deviceTime.GetDeviceTimeUtc(), // deviceTime.IsItTime(request.GetTimeSlicesFrom30()), deviceTime.TimeOneSidePathMsec, request.GetTimeSlicesFrom30())); if (!deviceTime.IsItTime(request.GetTimeSlicesFrom30().AddSeconds(10))) { return(new OperationResult(Quality.Bad, "Time has not yet come")); } } OperationResult result; try { byte[] arr = new byte[5]; arr[0] = BitwiseUtils.DecToBCD(request.Day); arr[1] = BitwiseUtils.DecToBCD(request.Month); arr[2] = BitwiseUtils.DecToBCD((byte)(request.TimeSlices.Year - 2000)); arr[3] = request.Index; arr[4] = 1; var send = CreateRequest(request.Address, Codes.CODE_READ_ENERGY_INTERVAL, psw, arr); result = WriteReadCheck(channel, nRepeatGlobal, send, out byte[] answer); Array.Resize <byte>(ref answer, 4); var seg = new ByteArraySegment(answer, 0, answer.Length); var value = seg.ReadUInt32(0); if (value == 0xFFFFFF) { response = new Energy(0, 0, 0, 0); //это значит что его нет в памяти и надо возвращать нули return(OperationResult.Bad); } response = new Energy(value, 0, 0, 0); result = OperationResult.Good; } catch (Exception e) { result = OperationResult.From(e); } return(result); }
/// <summary> /// Чтение приращений (показаний) /// </summary> /// <param name="fromTime"></param> /// <param name="typeQuery"></param> /// <param name="typeInc"></param> /// <param name="aplus"></param> /// <param name="aminus"></param> /// <param name="rplus"></param> /// <param name="rminus"></param> /// <param name="depth"></param> /// <param name="deepSyncTime"></param> /// <param name="tariff"> /// Добавлена поддержка чтения тарифов для показаний, т.к. эту величину нельзя расчитать. /// </param> static internal void ReadInc( QueryInfo info, DateTimeZone fromTime, TypeQuery typeQuery, TypeInc typeInc, TagDef aplus, TagDef aminus, TagDef rplus, TagDef rminus, int depth, DateTimeUtc deepSyncTime, ETariff tariff = ETariff.NoTariff) { //Если в гране нет данных то дальше этой даты записываем что нельзя востонавить bool fillBadNoRestore = false; int itemNum = 0; OperationResult oper = new OperationResult(Quality.Bad); var holes = info.GetHoles(typeInc, fromTime, depth, deepSyncTime, new[] { aplus }); var reversedHoles = holes.Reverse(); foreach (var item in reversedHoles) { itemNum++; Energy read = null; OperationResult res = OperationResult.Bad; if (fillBadNoRestore) { read = new Energy(0, 0, 0, 0); oper = new OperationResult(Quality.BadNoRestore); } else if (info.Session.BeginOperation()) { if (DataBusSetting.StubData) //STUBDATA-> { read = new Energy(StubUtil.Int32(500), StubUtil.Int32(600), StubUtil.Int32(700), StubUtil.Int32(800)); oper = new OperationResult(Quality.Good); } else { switch (typeQuery) { #region (case TypeQuery.SlicesEnergy:) case TypeQuery.SlicesEnergy: if (!info.IsHalfHourInterval) { oper = new OperationResult(Quality.Bad, "HalfHour Interval is incorrect!"); } else { // только для версий СЕ102 S7, R8, CE301M S31, R33 // версии CE102 S6, R5 не поддерживают архив получасов oper = info.Request.TryReadSlicesEnergy( info.DataBus, info.Cs.Psw, info.Session.TimeDevice, SlicesQuery.From(item, info.Cs.Address), out read); read.Calc(info.DeviceKoef); } break; #endregion #region (case TypeQuery.Counter:) case TypeQuery.Counter: oper = info.Request.TryReadCounter( info.DataBus, info.Cs.Psw, typeInc, RequestIndex.From(item, typeInc, info.Cs.Address, true), tariff, out read); read.Calc(info.DeviceKoef); break; #endregion /*#region (case TypeQuery.Power3min:) * case TypeQuery.Power3min: * AvPowerIndex pi; * oper = info.Request.TryReadAvPower3min( * info.DataBus, * info.Session.TimeDevice, * info.Session.Zone, * RequestIndex.From(item, typeInc, info.Cs.Address, false), * item, * out pi); * if (oper.IsGood) * read = pi.Power.ToEnergy(20); * break; #endregion*/ } //Может возникать ситуация когда на компе уже наступило время опроса а на счетчике нет и будет возвращен блок поврежден //TODO if ((itemNum < 3) && (oper.Quality == Quality.BadNoRestore)) oper.Quality = Quality.Bad; } /*if ((!oper.IsGood) && (oper.Code == 2)) * { * if (info.Session.OpenData.NewDevice != ChangeDeviceInfo.None) * info.LogWarn(SR.NOT_PARAM, info.DisplayName, aplus.AccountKind, aplus.Discrete, aplus.DiscreteValue); * info.Session.EndOperation(OperationResult.Good); * break; //Неизвестная функция не подерживаемая версией устройства * }*/ info.Session.EndOperation(oper); if (!oper.IsGood) { read = new Energy(0, 0, 0, 0); info.DataBus.DiscardInBuffer(); } if (oper.Quality == Quality.BadNoRestore) { fillBadNoRestore = true; //заполним все полохими не востанавливаемыми } } else { break; } info.Storage.WriteTagsValue( HW(oper.Quality, read.Aplus, item, aplus), HW(Quality.Bad, read.Aminus, item, aminus), HW(Quality.Bad, read.Rplus, item, rplus), HW(Quality.Bad, read.Rminus, item, rminus)); if (info.Log.Trace.IsOn(2)) { var sb = new StringBuilder(); sb.AppendFormat("Read from [{0}] {1} {2}", item, typeInc, oper.Quality); if (typeQuery != TypeQuery.SlicesEnergy) { sb.Append(" " + typeQuery); } if (!oper.IsGood) { sb.AppendFormat(". Error: {0}", oper.ErrorMsg); info.Log.Trace.Error(2, sb.ToString()); } else { sb.AppendFormat(". A+: {0}, A-: {1}, R+: {2}, R-: {3}", read.Aplus, read.Aminus, read.Rplus, read.Rminus); info.Log.Trace.Info(2, sb.ToString()); } } } }