/// <summary> /// Чтение срезов мощности за период времени /// </summary> /// <param name="dt_begin"></param> /// <param name="dt_end"></param> /// <param name="listRPS">Выходной лист срезов мощности</param> /// <param name="period">Время через которые записаны срезы (устанавливается при инициализации срезов мощности)</param> /// <returns></returns> public bool ReadPowerSlice(DateTime dt_begin, DateTime dt_end, ref List<RecordPowerSlice> listRPS, byte period) { ushort addr_before = 0; ushort addr_after = 0; ushort diff = 0; byte[] tmp_buf = new byte[9]; byte[] buf = new byte[2]; LastPowerSlice lps = new LastPowerSlice(); RecordPowerSlice record_slice = new RecordPowerSlice(); DateTime dt_lastslice; // проверка: данный вариант исполнения счетчика не поддерживает учет срезов if (!m_presenceProfile) { return false; } // читаем последний срез if (!ReadLastSlice(ref lps)) { return false; } try { // Время последнего среза из счётчика dt_lastslice = new DateTime(lps.year, lps.month, lps.day, lps.hour, lps.minute, 0); } catch { return false; } if (dt_begin >= dt_lastslice) return false; // Вычисляем разницу в минутах TimeSpan span = dt_lastslice - dt_begin; int diff_minutes = Convert.ToInt32(span.TotalMinutes); // если разница > max кол-ва хранящихся записей в счётчике, то не вычитываем их из счётчика while (diff_minutes >= (4096 * period)) { dt_begin = dt_begin.AddMinutes(period); span = dt_lastslice - dt_begin; diff_minutes = span.Minutes; } //Вычисляем разницу в срезах diff = Convert.ToUInt16(diff_minutes / period); ushort address_slice = diff; // Увеличиваем время на 30 минут //dt_begin = dt_begin.AddMinutes(30); // Уменьшаем адрес среза //address_slice--; for (ushort i = 0; i <= diff; i++) { // меняем байты в слове местами addr_before = Convert.ToUInt16(((lps.addr & 0xff) << 8) | ((lps.addr & 0xFF00) >> 8)); // делаем смещение addr_before -= Convert.ToUInt16(address_slice * 0x10); // возвращаем байты на прежнее положение addr_after = Convert.ToUInt16(((addr_before & 0xff) << 8) | ((addr_before & 0xFF00) >> 8)); // чтение среза по рассчитанному адресу bool res_read_slice = ReadSlice(addr_after, ref record_slice, period); // this.Open(); // bool res_read_slice = ReadSlice(0x10f0, ref record_slice, period); // Если при чтении не было ошибок if (res_read_slice) { // проверка на то, что прочитанный срез старый if (dt_begin > record_slice.date_time) record_slice.status = 0xFE; else listRPS.Add(record_slice); /* else if (dt_begin == record_slice.date_time) { listRPS.Add(record_slice); } */ } if (address_slice > 0) { // Увеличиваем время на 30 минут dt_begin = dt_begin.AddMinutes(period); // Уменьшаем адрес среза address_slice--; } } return true; }
/// <summary> /// Чтение информации о последнем зафиксированнрм счетчиком среза /// </summary> /// <param name="lps"></param> /// <returns></returns> private bool ReadCurrentPowerSliceInfo(ref LastPowerSlice lps) { byte[] answer = new byte[RLASTSLICE_ANSW_SIZE]; byte[] command = new byte[] { 0x08, 0x4 }; // Читаем последний срез мощности для определения адреса физической памяти последней записи массива if (!SendCommand(command, ref answer, 2, RLASTSLICE_ANSW_SIZE)) return false; try { byte[] temp = new byte[2] { answer[7], answer[6] }; // адрес последней записи lps.addr = BitConverter.ToUInt16(temp, 0); // признак перезаписи области профиля lps.reload = ((answer[1] & 0x80) == 0x80) ? true : false; // конвертируем время из DEC в HEX int minute = CommonMeters.DEC2HEX(Convert.ToByte(answer[1] & 0x7F)); int hour = CommonMeters.DEC2HEX(answer[2]); int day = CommonMeters.DEC2HEX(answer[3]); int month = CommonMeters.DEC2HEX(answer[4]); int year = CommonMeters.DEC2HEX(answer[5]) + 2000; //minute = (minute > 15 && minute < 45) ? 30 : 00; //WriteToLog("ReadCurrentPowerSliceInfo datetime: minute" + answer[1].ToString("x") + " hour=" + hour.ToString() + " day=" + day.ToString() + " month=" + month.ToString() + " year=" + year.ToString()); lps.dt = new DateTime(year, month, day, hour, minute, 0); //WriteToLog("Last power slice: Reload=" + lps.reload.ToString() + // "; Address=" + lps.addr.ToString() + // "; Datetime=" + lps.dt.ToShortDateString() + " " + lps.dt.ToShortTimeString()); } catch (Exception ex) { WriteToLog("ReadCurrentPowerSliceInfo - " + ex.Message); return false; } return true; }
/// <summary> /// Чтение информации о последнем зафиксированнрм счетчиком среза /// </summary> /// <param name="lps"></param> /// <returns></returns> public bool ReadLastSlice(ref LastPowerSlice lps) { byte[] answer = new byte[RLASTSLICE_ANSW_SIZE]; byte[] command = new byte[] { 0x08, 0x13 }; byte status = 0; // Читаем последний срез мощности для определения адреса физической памяти последней записи массива if (!SendCommand(command, ref answer, 2, RLASTSLICE_ANSW_SIZE, ref status)) return false; // Длительность периода интенрирования lps.len = answer[9]; // конвертируем время из DEC в HEX lps.minute = dec2hex(answer[5]); lps.hour = dec2hex(answer[4]); lps.day = dec2hex(answer[6]); lps.month = dec2hex(answer[7]); lps.year = dec2hex(answer[8]) + 2000; if (lps.minute > 15 && lps.minute < 45) lps.minute = 30; if (lps.minute >= 45 && lps.minute <= 59) lps.minute = 60; // адрес последней записи lps.addr = BitConverter.ToUInt16(answer, 1); // признак перезаписи области профиля if ((answer[3] & 0x1) == 1) lps.reload = true; else lps.reload = false; // рассчёт адреса хранения самого раннего среза if (lps.reload) m_diff_slices = 4096; else m_diff_slices = Convert.ToUInt16(lps.addr / (ushort)0x10); return true; }
/* /// <summary> /// Чтение параметров качества энергии /// </summary> /// <param name="values"></param> /// <returns></returns> private void PowerQualityParams(ref Values values) { RecordParamsEnergy recParams = new RecordParamsEnergy(); // читаем частоту сети, Гц if (m_types_for_read_power_quality_params.Contains((byte)TypesValues.Frequency)) { if (this.ReadParams(0x40, ref recParams)) { RecordValue iv; iv.fine_state = true; iv.type = (byte)TypesValues.Frequency; iv.value = recParams.phase_sum; values.listRV.Add(iv); //WriteToLog("F = " + recParams.phase_sum.ToString()); } } // читаем напряжение, В if (m_types_for_read_power_quality_params.Contains((byte)TypesValues.UA) | m_types_for_read_power_quality_params.Contains((byte)TypesValues.UB) | m_types_for_read_power_quality_params.Contains((byte)TypesValues.UC) ) { if (this.ReadParams(0x11, ref recParams)) { RecordValue iv; iv.fine_state = true; iv.type = (byte)TypesValues.UA; iv.value = recParams.phase_1; values.listRV.Add(iv); iv.type = (byte)TypesValues.UB; iv.value = recParams.phase_2; values.listRV.Add(iv); iv.type = (byte)TypesValues.UC; iv.value = recParams.phase_3; values.listRV.Add(iv); //WriteToLog("Ua = " + recParams.phase_1.ToString() + "; Ub = " + recParams.phase_2.ToString() + "; Uc = " + recParams.phase_3.ToString()); } } // читаем ток, А if (m_types_for_read_power_quality_params.Contains((byte)TypesValues.IA) | m_types_for_read_power_quality_params.Contains((byte)TypesValues.IB) | m_types_for_read_power_quality_params.Contains((byte)TypesValues.IC) ) { if (this.ReadParams(0x21, ref recParams)) { RecordValue iv; iv.fine_state = true; iv.type = (byte)TypesValues.IA; iv.value = recParams.phase_1; values.listRV.Add(iv); iv.type = (byte)TypesValues.IB; iv.value = recParams.phase_2; values.listRV.Add(iv); iv.type = (byte)TypesValues.IC; iv.value = recParams.phase_3; values.listRV.Add(iv); //WriteToLog("Ia = " + recParams.phase_1.ToString() + "; Ib = " + recParams.phase_2.ToString() + "; Ic = " + recParams.phase_3.ToString()); } } // читаем коэффициенты мощности cos if (m_types_for_read_power_quality_params.Contains((byte)TypesValues.COS) | m_types_for_read_power_quality_params.Contains((byte)TypesValues.COSA) | m_types_for_read_power_quality_params.Contains((byte)TypesValues.COSB) | m_types_for_read_power_quality_params.Contains((byte)TypesValues.COSC) ) { if (this.ReadParams(0x30, ref recParams)) { RecordValue iv; iv.fine_state = true; iv.type = (byte)TypesValues.COSA; iv.value = recParams.phase_1; values.listRV.Add(iv); iv.type = (byte)TypesValues.COSB; iv.value = recParams.phase_2; values.listRV.Add(iv); iv.type = (byte)TypesValues.COSC; iv.value = recParams.phase_3; values.listRV.Add(iv); iv.type = (byte)TypesValues.COS; iv.value = recParams.phase_sum; values.listRV.Add(iv); //WriteToLog("cos =" + recParams.phase_sum.ToString() + "; cosA = " + recParams.phase_1.ToString() + "; cosB = " + recParams.phase_2.ToString() + "; cosC = " + recParams.phase_3.ToString()); } } // читаем мощность P, Вт if (m_types_for_read_power_quality_params.Contains((byte)TypesValues.P) | m_types_for_read_power_quality_params.Contains((byte)TypesValues.PA) | m_types_for_read_power_quality_params.Contains((byte)TypesValues.PB) | m_types_for_read_power_quality_params.Contains((byte)TypesValues.PC) ) { if (this.ReadParams(0x0, ref recParams)) { RecordValue iv; iv.fine_state = true; iv.type = (byte)TypesValues.PA; iv.value = recParams.phase_1; values.listRV.Add(iv); iv.type = (byte)TypesValues.PB; iv.value = recParams.phase_2; values.listRV.Add(iv); iv.type = (byte)TypesValues.PC; iv.value = recParams.phase_3; values.listRV.Add(iv); iv.type = (byte)TypesValues.P; iv.value = recParams.phase_sum; values.listRV.Add(iv); //WriteToLog("PSum =" + recParams.phase_sum.ToString() + "; Pa = " + recParams.phase_1.ToString() + "; Pb = " + recParams.phase_2.ToString() + "; Pc = " + recParams.phase_3.ToString()); } } // читаем мощность S, ВА if (m_types_for_read_power_quality_params.Contains((byte)TypesValues.S) | m_types_for_read_power_quality_params.Contains((byte)TypesValues.SA) | m_types_for_read_power_quality_params.Contains((byte)TypesValues.SB) | m_types_for_read_power_quality_params.Contains((byte)TypesValues.SC) ) { if (this.ReadParams(0x8, ref recParams)) { RecordValue iv; iv.fine_state = true; iv.type = (byte)TypesValues.SA; iv.value = recParams.phase_1; values.listRV.Add(iv); iv.type = (byte)TypesValues.SB; iv.value = recParams.phase_2; values.listRV.Add(iv); iv.type = (byte)TypesValues.SC; iv.value = recParams.phase_3; values.listRV.Add(iv); iv.type = (byte)TypesValues.S; iv.value = recParams.phase_sum; values.listRV.Add(iv); //WriteToLog("SSum =" + recParams.phase_sum.ToString() + "; Sa = " + recParams.phase_1.ToString() + "; Sb = " + recParams.phase_2.ToString() + "; Sc = " + recParams.phase_3.ToString()); } } // читаем мощность Q, Вар if (m_types_for_read_power_quality_params.Contains((byte)TypesValues.Q) | m_types_for_read_power_quality_params.Contains((byte)TypesValues.QA) | m_types_for_read_power_quality_params.Contains((byte)TypesValues.QB) | m_types_for_read_power_quality_params.Contains((byte)TypesValues.QC) ) { if (this.ReadParams(0x4, ref recParams)) { RecordValue iv; iv.fine_state = true; iv.type = (byte)TypesValues.QA; iv.value = recParams.phase_1; values.listRV.Add(iv); iv.type = (byte)TypesValues.QB; iv.value = recParams.phase_2; values.listRV.Add(iv); iv.type = (byte)TypesValues.QC; iv.value = recParams.phase_3; values.listRV.Add(iv); iv.type = (byte)TypesValues.Q; iv.value = recParams.phase_sum; values.listRV.Add(iv); //WriteToLog("QSum =" + recParams.phase_sum.ToString() + "; Qa = " + recParams.phase_1.ToString() + "; Qb = " + recParams.phase_2.ToString() + "; Qc = " + recParams.phase_3.ToString()); } } } */ public bool ReadPowerSlice(ref List<RecordPowerSlice> listRPS, DateTime dt_begin, byte period) { try { // читаем последний срез LastPowerSlice lps = new LastPowerSlice(); if (!ReadCurrentPowerSliceInfo(ref lps)) { return false; } // Вычисляем разницу в часах TimeSpan span = lps.dt - dt_begin; int diff_hours = Convert.ToInt32(span.TotalHours); // если разница > max кол-ва хранящихся записей в счётчике, то не вычитываем их из счётчика if (diff_hours >= m_depth_storage_power_slices) { diff_hours = m_depth_storage_power_slices; } if (diff_hours > (lps.addr / 24)) { diff_hours = lps.addr / 24; } //WriteToLog("differense hours=" + diff_hours.ToString() + "; reload=" + lps.reload.ToString() + "; dt_begin=" + dt_begin.ToString()); List<RecordPowerSlice> lRPS = new List<RecordPowerSlice>(); for (int i = diff_hours; i > 0; i--) { int add_minus_val = (lps.dt.Minute == 0) ? 8 : 16; int addr = lps.addr - Convert.ToUInt16(m_size_record_power_slices * i) - (ushort)add_minus_val; ushort address_slice = (addr < 0) ? Convert.ToUInt16(Convert.ToInt32(65536 + addr)) : Convert.ToUInt16(addr); // чтение среза по рассчитанному адресу и при чтении не было ошибок List<IndaySlice> record_slices = new List<IndaySlice>(); if (ReadSlice((ushort)address_slice, ref record_slices, period)) { foreach (IndaySlice ids in record_slices) { RecordPowerSlice rps = new RecordPowerSlice(); rps.APlus = (float)ids.values[0].value; rps.AMinus = (float)ids.values[1].value; rps.RPlus = (float)ids.values[2].value; rps.RMinus = (float)ids.values[3].value; rps.status = Convert.ToByte(!ids.not_full); rps.date_time = ids.date_time; rps.period = 30; lRPS.Add(rps); } } else { WriteToLog("ReadPowerSlice: slice has not been read"); break; } } if (lRPS.Count > 0) { listRPS = lRPS; return true; } } catch (Exception ex) { WriteToLog("ReadPowerSlice: " + ex.Message); return false; } return false; }