// Чтение среза мощности по указанному адресу bool ReadSlice(ushort addr_slice, ref RecordPowerSlice record_slice, byte period) { byte[] cmnd = new byte[32]; byte[] answer = new byte[RSLICE_ANSW_SIZE]; byte[] command = new byte[] { 0x06, 0x03 }; byte[] addr = new byte[2]; ushort temp_value = 0; float value = 0; byte status = 0; cmnd[0] = command[0]; cmnd[1] = command[1]; addr = BitConverter.GetBytes(addr_slice); cmnd[2] = addr[0]; cmnd[3] = addr[1]; cmnd[4] = 0x0F; this.Open(); if (!SendCommand(cmnd, ref answer, 5, RSLICE_ANSW_SIZE, ref status)) { if (status == 0x2) record_slice.status = 0xFE; return false; } // длительность периода интегрирования record_slice.period = answer[7]; // время записи среза int hour = dec2hex(answer[2]); int minute = dec2hex(answer[3]); int day = dec2hex(answer[4]); int month = dec2hex(answer[5]); int year = dec2hex(answer[6]) + 2000; try { record_slice.date_time = new DateTime(year, month, day, hour, minute, 0); } catch { return false; } // делаем даты кратными 00 и 30 if (record_slice.date_time.Minute > 15 && record_slice.date_time.Minute < 30) record_slice.date_time = record_slice.date_time.AddMinutes(30 - record_slice.date_time.Minute); else if (record_slice.date_time.Minute > 30 && record_slice.date_time.Minute < 45) { record_slice.date_time = record_slice.date_time.AddMinutes(30 - record_slice.date_time.Minute); } else if (record_slice.date_time.Minute >= 45 && record_slice.date_time.Minute <= 59) { record_slice.date_time = record_slice.date_time.AddMinutes(60 - record_slice.date_time.Minute); } else if (record_slice.date_time.Minute > 0 && record_slice.date_time.Minute <= 15) record_slice.date_time = record_slice.date_time.AddMinutes(-1 * record_slice.date_time.Minute); // Статус среза if (((answer[1] >> 0x1) & 1) == 0) record_slice.status = 0; else record_slice.status = 0xFE; // Разбираем по видам энергии for (int i = 0; i <= 3; i++) { temp_value = BitConverter.ToUInt16(answer, 8 + i * 2); if (temp_value == 0xFFFF) temp_value = 0; //string s = Convert.ToString(this.m_address) + ": Ratio: " + Convert.ToString(m_GearRatio) + "; tempValue=" + Convert.ToString(temp_value); //WriteToLog(s); value = Convert.ToSingle(((float)temp_value * (60 / period)) / ((float)m_GearRatio * 2 * 2));//*2 добавлено 24.03 в кВт switch (i) { case 0: // активная прямая record_slice.APlus = value; break; case 1: // активная обратная record_slice.AMinus = value; break; case 2: // реактивная прямая record_slice.RPlus = value; break; case 3: // реактивная обратная record_slice.RMinus = value; break; } } return true; }
/// <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="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; }