private bool ParseDumpFile(string fileName, ref MeterInfo mi, ref Params prms, bool deleteAfterParse = false) { mi = new MeterInfo(); prms = new Params(); string strValues = ""; if (!File.Exists(fileName)) return false; try { FileStream dumpFileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); bool tmpRes = false; if (GetMeterInfo(dumpFileStream, ref mi)) if (FillParamsStructure(dumpFileStream, out prms, out strValues)) tmpRes = true; dumpFileStream.Close(); if (tmpRes && deleteAfterParse) DeleteDumpFileAndLogs(fileName); return tmpRes; } catch (Exception ex) { return false; } }
public bool FillParamsStructure(FileStream fsDump, out Params structParams, out string strRepresentation) { structParams = new Params(); strRepresentation = ""; byte[] sourceBytes = null; if (fsDump != null) { try { //СНАЧАЛА ВСЕ ПАРАМЕТРЫ ИЗ EEPROM //Q structParams.Q = new float[2]; MeterParam Q1 = EEPROMParamList.Find((x) => { return x.PName == "Q1"; }); fsDump.Seek(Q1.PIndex, SeekOrigin.Begin); Q1.PValue = GiveMeNextValue(fsDump, Q1.PLength, ref sourceBytes); Q1.PValue /= Q1.Coefficient; structParams.Q[0] = RoundFloat(Q1.PValue); MeterParam Q2 = EEPROMParamList.Find((x) => { return x.PName == "Q2"; }); Q2.PValue = GiveMeNextValue(fsDump, Q2.PLength, ref sourceBytes); Q2.PValue /= Q2.Coefficient; structParams.Q[1] = RoundFloat(Q2.PValue); for (int i = 0; i < structParams.Q.Length; i++) strRepresentation += String.Format("Q{0}: {1}{2}; ", i + 1, structParams.Q[i], " " + Q1.PUnit); //M structParams.M = new float[4]; MeterParam M1 = EEPROMParamList.Find((x) => { return x.PName == "M1"; }); M1.PValue = GiveMeNextValue(fsDump, M1.PLength, ref sourceBytes); M1.PValue /= M1.Coefficient; structParams.M[0] = RoundFloat(M1.PValue); MeterParam M2 = EEPROMParamList.Find((x) => { return x.PName == "M2"; }); M2.PValue = GiveMeNextValue(fsDump, M2.PLength, ref sourceBytes); M2.PValue /= M2.Coefficient; structParams.M[1] = RoundFloat(M2.PValue); MeterParam M3 = EEPROMParamList.Find((x) => { return x.PName == "M3"; }); M3.PValue = GiveMeNextValue(fsDump, M3.PLength, ref sourceBytes); M3.PValue /= M3.Coefficient; structParams.M[2] = RoundFloat(M3.PValue); MeterParam M4 = EEPROMParamList.Find((x) => { return x.PName == "M4"; }); M4.PValue = GiveMeNextValue(fsDump, M4.PLength, ref sourceBytes); M4.PValue /= M4.Coefficient; structParams.M[3] = RoundFloat(M4.PValue); for (int i = 0; i < structParams.M.Length; i++) strRepresentation += String.Format("M{0}: {1}{2}; ", i + 1, structParams.M[i], " " + M1.PUnit); //V structParams.V = new float[4]; MeterParam V1 = EEPROMParamList.Find((x) => { return x.PName == "V1"; }); V1.PValue = GiveMeNextValue(fsDump, V1.PLength, ref sourceBytes); V1.PValue /= V1.Coefficient; structParams.V[0] = RoundFloat(V1.PValue); MeterParam V2 = EEPROMParamList.Find((x) => { return x.PName == "V2"; }); V2.PValue = GiveMeNextValue(fsDump, V2.PLength, ref sourceBytes); V2.PValue /= V2.Coefficient; structParams.V[1] = RoundFloat(V2.PValue); MeterParam V3 = EEPROMParamList.Find((x) => { return x.PName == "V3"; }); V3.PValue = GiveMeNextValue(fsDump, V3.PLength, ref sourceBytes); V3.PValue /= V3.Coefficient; structParams.V[2] = RoundFloat(V3.PValue); MeterParam V4 = EEPROMParamList.Find((x) => { return x.PName == "V4"; }); V4.PValue = GiveMeNextValue(fsDump, V4.PLength, ref sourceBytes); V4.PValue /= V4.Coefficient; structParams.V[3] = RoundFloat(V4.PValue); for (int i = 0; i < structParams.V.Length; i++) strRepresentation += String.Format("V{0}: {1}{2}; ", i + 1, structParams.V[i], " " + V1.PUnit); } catch (Exception ex) { fsDump.Close(); return false; } try { //ТЕПЕРЬ ПЕРЕМЕСТИМСЯ К КРАЙНЕЙ ЧАСОВОЙ ЗАПИСИ //Внимание! В часовых записях, хранится только приращение величины за последний час (кроме T и служебных параметров) int offsetFromTheEnd = ((int)bytesFromTheEnd + RecordLength) * -1; fsDump.Seek(offsetFromTheEnd, SeekOrigin.End); //T structParams.T = new float[4]; MeterParam T1 = HourRecordParamList.Find((x) => { return x.PName == "T1"; }); fsDump.Seek(T1.PIndex, SeekOrigin.Current); GiveMeNextValue(fsDump, T1.PLength, ref sourceBytes); if (sourceBytes[1] > 0) T1.PValue = sourceBytes[1] + T1.Coefficient; T1.PValue += (float)sourceBytes[0] / T1.Coefficient2; structParams.T[0] = RoundFloat(T1.PValue); MeterParam T2 = HourRecordParamList.Find((x) => { return x.PName == "T2"; }); GiveMeNextValue(fsDump, T2.PLength, ref sourceBytes); if (sourceBytes[1] > 0) T2.PValue = sourceBytes[1] + T2.Coefficient; T2.PValue += (float)sourceBytes[0] / T2.Coefficient2; structParams.T[1] = RoundFloat(T2.PValue); MeterParam T3 = HourRecordParamList.Find((x) => { return x.PName == "T3"; }); GiveMeNextValue(fsDump, T3.PLength, ref sourceBytes); if (sourceBytes[1] > 0) T3.PValue = sourceBytes[1] + T3.Coefficient; T3.PValue += (float)sourceBytes[0] / T3.Coefficient2; structParams.T[2] = RoundFloat(T3.PValue); MeterParam T4 = HourRecordParamList.Find((x) => { return x.PName == "T4"; }); GiveMeNextValue(fsDump, T4.PLength, ref sourceBytes); if (sourceBytes[1] > 0) T4.PValue = sourceBytes[1] + T4.Coefficient; T4.PValue += (float)sourceBytes[0] / T4.Coefficient2; structParams.T[3] = RoundFloat(T4.PValue); for (int i = 0; i < structParams.T.Length; i++) strRepresentation += String.Format("T{0}: {1}{2}; ", i + 1, structParams.T[i], " " + T1.PUnit); //ETC fsDump.Seek(offsetFromTheEnd, SeekOrigin.End); structParams.NC = new int[2]; MeterParam NC1 = HourRecordParamList.Find((x) => { return x.PName == "НС1"; }); fsDump.Seek(NC1.PIndex, SeekOrigin.Current); NC1.PValue = GiveMeNextValue(fsDump, NC1.PLength, ref sourceBytes); structParams.NC[0] = (int)NC1.PValue; MeterParam NC2 = HourRecordParamList.Find((x) => { return x.PName == "НС2"; }); NC2.PValue = GiveMeNextValue(fsDump, NC2.PLength, ref sourceBytes); NC2.PValue /= NC2.Coefficient; structParams.VoltsBattery = NC2.PValue; MeterParam Ubat = HourRecordParamList.Find((x) => { return x.PName == "Uбат"; }); fsDump.Seek(offsetFromTheEnd, SeekOrigin.End); fsDump.Seek(Ubat.PIndex, SeekOrigin.Current); Ubat.PValue = GiveMeNextValue(fsDump, Ubat.PLength, ref sourceBytes); Ubat.PValue /= Ubat.Coefficient; structParams.VoltsBattery = Ubat.PValue; for (int i = 0; i < structParams.NC.Length; i++) strRepresentation += String.Format("Вычислитель {0}: {1} [{2}];\n", i + 1, structParams.NC[i], GetNSDescription(structParams.NC[i])); strRepresentation += String.Format("U батареи: {1}{2}; ", "", structParams.VoltsBattery, " " + Ubat.PUnit); } catch (Exception ex) { fsDump.Close(); return false; } fsDump.Close(); return true; } return false; }
private bool GetParamValueFromParams(Params prms, ushort param, ushort tarif, out float recordValue) { recordValue = -1; switch (param) { case 0: { //тепловая энергия float k = 1; if (tarif > 0 && tarif < 3) { recordValue = prms.Q[tarif - 1] * k; return true; } return false; } case 1: { //температура float k = 1; if (tarif > 0 && tarif < 5) { recordValue = prms.T[tarif - 1] * k; return true; } return false; } case 2: { //масса float k = 1; if (tarif > 0 && tarif < 5) { recordValue = prms.M[tarif - 1] * k; return true; } return false; } } return false; }
public bool ReadDailyValues(DateTime dt, ushort param, ushort tarif, ref float recordValue) { recordValue = -1; bool DELETE_DUMPS_AFTER_PARSING = false; MeterInfo tmpMi = new MeterInfo(); Params tmpPrms = new Params(); //находится ли в каталоге утилита rdslib.exe if (!DoLibraryExists()) return false; //проверим есть ли дамп и старше ли он чем readDailyTimeoutInDays string curDumpDir = directoryBase + DIR_NAME_LIB + "\\" + DIR_NAME_DUMPS; if (!Directory.Exists(curDumpDir)) Directory.CreateDirectory(curDumpDir); string LogTerminationCode = ""; if (IsReadingBlocked(blockingTimeMinutes, curDumpDir, m_address.ToString(), ref LogTerminationCode)) return false; string latestDumpFileName = ""; DateTime latestDumpDate = new DateTime(); FileInfo latestDumpFileInfo = null; if (LatestByDateFileInfo(curDumpDir, m_address.ToString(), ref latestDumpFileInfo, "*.dat")) { latestDumpFileName = latestDumpFileInfo.FullName; latestDumpDate = latestDumpFileInfo.LastWriteTime.Date; if (File.Exists(latestDumpFileName)) { DateTime dateCur = DateTime.Now.Date; TimeSpan ts = dateCur - latestDumpDate; //если мы дошли до сюда, то искомого параметра нет в таблице "суточные" (см. mainservice) //чтобы не дергать счетчик, введено ограничение - мы реально запрашиваем дамп со //только раз в readDailyTimeoutInDays суток, поэтому: // //если прошло меньше чем readDailyTimeoutInDays дней if (ts.TotalDays < readDailyTimeoutInDays) { //прочитаем недостающий параметр из уже существующего дампа //чтобы не дергать счетчик if (ParseDumpFile(latestDumpFileName, ref tmpMi, ref tmpPrms, DELETE_DUMPS_AFTER_PARSING)) if (GetParamValueFromParams(tmpPrms, param, tarif, out recordValue)) return true; } } } //если мы дошли до сюда, то, либо подошло время обновить дамп, либо проблемы с разбором существующего //если прошло менее N дней, но искомого параметра еще нет DeleteDumpFileAndLogs(latestDumpFileName); //ниже нельзя просто вызвать чтение суточных, т.к. суточные удаляют дамп сразу //после разбора, поэтому дублируем //попытаемся найти BAT файл string curBatchDirectory = directoryBase + DIR_NAME_LIB + "\\" + DIR_NAME_BATCH; string curBatchFilename = curBatchDirectory + "\\" + m_address + ".bat"; if (!Directory.Exists(curBatchDirectory) || !File.Exists(curBatchFilename)) return false; //ВСЕ ГОТОВО К РЕАЛЬНОМУ ЧТЕНИЮ И ГЕНЕРАЦИИ ДАМПА FileInfo batchFileInfo = new FileInfo(curBatchFilename); List<FileInfo> batchFIList = new List<FileInfo>(); batchFIList.Add(batchFileInfo); List<BatchConnection> batchConnList = new List<BatchConnection>(); if (!CreateBatchConnectionList(batchFIList, ref batchConnList)) return false; if (!ExecuteBatchConnection(batchConnList[0])) return false; if (!ParseDumpFile(batchConnList[0].FileNameDump, ref tmpMi, ref tmpPrms, DELETE_DUMPS_AFTER_PARSING)) return false; if (!GetParamValueFromParams(tmpPrms, param, tarif, out recordValue)) return false; return true; }
public bool ReadCurrentValues(ushort param, ushort tarif, ref float recordValue) { recordValue = -1; //находится ли в каталоге утилита rdslib.exe if (!DoLibraryExists()) return false; //попытаемся найти BAT файл string curBatchDirectory = directoryBase + DIR_NAME_LIB + "\\" + DIR_NAME_BATCH; string curBatchFilename = curBatchDirectory + "\\" + m_address + ".bat"; if (!Directory.Exists(curBatchDirectory) || !File.Exists(curBatchFilename)) return false; string curDumpDir = directoryBase + DIR_NAME_LIB + "\\" + DIR_NAME_DUMPS; if (!Directory.Exists(curDumpDir)) Directory.CreateDirectory(curDumpDir); //все готово к генерации дампа FileInfo batchFileInfo = new FileInfo(curBatchFilename); List<FileInfo> batchFIList = new List<FileInfo>(); batchFIList.Add(batchFileInfo); List<BatchConnection> batchConnList = new List<BatchConnection>(); if (!CreateBatchConnectionList(batchFIList, ref batchConnList)) return false; if (!ExecuteBatchConnection(batchConnList[0])) return false; MeterInfo tmpMi = new MeterInfo(); Params tmpPrms = new Params(); if (!ParseDumpFile(batchConnList[0].FileNameDump, ref tmpMi, ref tmpPrms, true)) return false; if (!GetParamValueFromParams(tmpPrms, param, tarif, out recordValue)) return false; DeleteDumpFileAndLogs(batchConnList[0].FileNameDump); return true; }
private bool getRecordValueByParam(Params param, List<Record> records, out float value) { if (records == null && records.Count == 0) { WriteToLog("getRecordValueByParam: список записей пуст"); value = 0f; return false; } if ((int)param >= records.Count) { WriteToLog("getRecordValueByParam: параметра не существует в списке записей: " + param.ToString()); value = 0f; return false; } Record record = records[(int)param]; byte[] data = record.dataBytes.ToArray(); Array.Reverse(data); string hex_str = BitConverter.ToString(data).Replace("-", string.Empty); int COEFFICIENT = 1; switch (param) { case Params.FACTORY_NUMBER: { break; } case Params.ENERGY: { //коэффициент, согласно документации MBUS, после применения дает значение в KCal COEFFICIENT = 10; //однако, согласно документации elf, требуется представить в GCal COEFFICIENT *= (int)Math.Pow(10, 6); break; } case Params.POWER: { COEFFICIENT = 10; break; } case Params.VOLUME: case Params.VOLUME_IMP1: case Params.VOLUME_IMP2: case Params.VOLUME_IMP3: case Params.VOLUME_IMP4: case Params.VOLUME_FLOW: { COEFFICIENT = 1000; break; } case Params.TEMP_INP: case Params.TEMP_OUTP: { COEFFICIENT = 10; break; } case Params.TIME_ON: case Params.TIME_ON_ERR: { break; } default: { break; } } if (!float.TryParse(hex_str, out value)) { value = 0f; string mgs = String.Format("Ошибка преобразования параметра {0} во float, исходная строка: {1}", param.ToString(), hex_str); WriteToLog(mgs); return false; } else { value /= COEFFICIENT; return true; } }
public bool getRecordValueByParam(Params param, out float value) { List<Record> records = new List<Record>(); value = 0f; if (!GetRecordsList(out records)) { WriteToLog("getRecordValueByParam: can't split records"); return false; } float res_val = 0f; if (getRecordValueByParam(param, records, out res_val)) { value = res_val; return true; } else { WriteToLog("getRecordValueByParam: can't getRecordValueByParam: " + Params.FACTORY_NUMBER.ToString()); return false; } }