public RXmes SendCmd(byte[] data) { RXmes RXmes_ = new RXmes(); byte[] crc = Modbus.Utility.ModbusUtility.CalculateCrc(data); Array.Resize(ref data, data.Length + 2); data[data.Length - 2] = crc[0]; data[data.Length - 1] = crc[1]; rs_port.Write(data, 0, data.Length); // Отправляем запрос, ждем 100 мс и смотрим что пришло в ответ System.Threading.Thread.Sleep(timeout); if (rs_port.BytesToRead > 0) { byte[] answer = new byte[(int)rs_port.BytesToRead]; // Читаем буфер для анализа ответа на команду управления // если задержка по времени не верна rs_port.BytesToRead может измениться во время этой функции... Нужно предусмотреть rs_port.Read(answer, 0, rs_port.BytesToRead); RXmes_.ReadArr(answer); if (RXmes_.err == error_type.none) { DataTime_last_contact = DateTime.Now; } return(RXmes_); } RXmes_.err = error_type.NoConnect; return(RXmes_); // Если не пришло вообще никакого ответа, // возвращаем отрицательное значение }
public accumulEnergy CallAccumulEnergy(peroidQuery period, byte tariff, byte month = 1) // запрос накопленной энергии { // tariff = 0 - работа по всем тарифам ; byte[] mes = new byte[4]; mes[0] = address; mes[1] = 5; mes[2] = (byte)(((byte)period << 4) | month); mes[3] = tariff; RXmes Rxmes_ = SendCmd(mes); accumulEnergy EnergyStruct = new accumulEnergy(); if (Rxmes_.err == error_type.none) { if (Rxmes_.buff.Length > 16) { long[] longBuf = new long[4]; for (int i = 0; i < 4; i++) { byte[] newbyte = { Rxmes_.buff[4 * i + 1], Rxmes_.buff[4 * i + 2], Rxmes_.buff[4 * i + 3], Rxmes_.buff[4 * i + 4] }; longBuf[i] = (newbyte[1] << 24) + (newbyte[0] << 16) + (newbyte[3] << 8) + newbyte[2]; } EnergyStruct.active_energy_in = longBuf[0]; EnergyStruct.active_energy_out = longBuf[1]; EnergyStruct.reactive_energy_in = longBuf[2]; EnergyStruct.reactive_energy_out = longBuf[3]; EnergyStruct.error = 0; return(EnergyStruct); } } EnergyStruct.error = -1; return(EnergyStruct); }
/// <summary> /// /// </summary> /// <param name="level"></param> /// <param name="password"></param> /// <returns></returns> public int OpenChannel(byte level, byte[] password) { byte[] mes = new byte[password.Length + 3]; mes[0] = address; mes[1] = 1; // байт запроса mes[2] = level; Array.Copy(password, 0, mes, 3, password.Length); RXmes RXmes = SendCmd(mes); return(explainAnswer(RXmes)); }
error_type testAnswer(RXmes RXmes_) { if (RXmes_.err != error_type.NoConnect) { if ((RXmes_.buff[0] == address)) { return(error_type.none); } } return(RXmes_.err); }
public int explainAnswer(RXmes RXmes_) { if ((RXmes_.err != error_type.CRCErr) && (RXmes_.err != error_type.NoConnect)) { if ((RXmes_.buff[0] == address)) { return(RXmes_.buff[1]); } } return(-1); }
/// <summary> /// Запрос дополнительных параметров мощности, тока, коэффициента мощности /// </summary> /// <param name="param">тип перечисления BWIR_param</param> /// <param name="Num_Of_Phase">Номер фазы 1, 2, 3. Для Мощности и коэффициента мощности 0 - по сумме фаз</param> /// <param name="query">Номер функции для запроса. 14, 16 , 11 . По умолчанию 16 /// 14 - чтение зафиксрованных данных</param> /// <param name="powerType">The param Для чтения мощности - P, Q или S</param> /// <returns>Возвращает параметры Сумма, Фаза1, Фаза2, Фаза3. Или Значение для одной фазы</returns> /// /// public int[] CallAdditionalParameters(BWIR_param param, byte Num_Of_Phase, AdditionalParameters_query query = AdditionalParameters_query.h16, power powerType = power.P) { byte[] mes = new byte[4]; mes[0] = address; mes[1] = 0x08; mes[2] = (byte)query; if (param == BWIR_param.frequency) { Num_Of_Phase = 0; } mes[3] += (byte)(((byte)param << 4) + ((byte)powerType << 2) + Num_Of_Phase); RXmes Rxmes_ = SendCmd(mes); if (Rxmes_.buff != null) { if (((Rxmes_.buff.Length - 3) % 4) > 0) { int[] j = new int[(Rxmes_.buff.Length - 3) / 3]; for (int i = 0; i < j.Length; i++) { byte[] newbyte = { Rxmes_.buff[3 * i + 1], Rxmes_.buff[3 * i + 2], Rxmes_.buff[3 * i + 3] }; j[i] = (newbyte[0] << 16) + (newbyte[2] << 8) + newbyte[1]; } return(j); } else if ((Rxmes_.buff.Length - 3) == 12) // ответ включает Сумма + 1ф + 2ф + 3ф = 12байт { int[] j = new int[4]; for (int i = 0; i < j.Length; i++) { byte[] newbyte = { Rxmes_.buff[3 * i + 1], Rxmes_.buff[3 * i + 2], Rxmes_.buff[3 * i + 3] }; // 6 бит 1 байта данных - направление реактивной мощности этот бит обнуляем // 7 бит - направление активной мощности . j[i] = ((newbyte[0] & 128) == 1 ? -1 : 1) * ((newbyte[0] & 0x3F) << 16) + (newbyte[2] << 8) + newbyte[1]; } return(j); } else { int[] j = new int[(Rxmes_.buff.Length - 3) / 4]; for (int i = 0; i < j.Length; i++) { byte[] newbyte = { Rxmes_.buff[4 * i + 1], Rxmes_.buff[4 * i + 2], Rxmes_.buff[4 * i + 3], Rxmes_.buff[4 * i + 4] }; j[i] = (newbyte[1] << 24) + (newbyte[0] << 16) + (newbyte[3] << 8) + newbyte[2]; } return(j); } } return(null); }
/// <summary> /// Получение серийного номера и даты выпуска /// </summary> /// <returns>Возвращает массив байт. Первые 3 байта - дата выпуска. Далее серийный номер</returns> public byte[] GiveSerialNumber() { byte[] mes = { address, 0x08, 0 }; RXmes RXmes = SendCmd(mes); if (RXmes.err == error_type.none) { byte[] bytebuf = new byte[7]; Array.Copy(RXmes.buff, 1, bytebuf, 0, 7); return(bytebuf); } return(null); }
public elecMeterDateTime CallTime() { elecMeterDateTime elecMeterDateTime_ = new elecMeterDateTime(); byte[] mes = { address, 0x04, 0x00 }; RXmes RXmes = SendCmd(mes); if (RXmes.err == error_type.none) { elecMeterDateTime_.dateFromAnswer(RXmes.buff); } return(elecMeterDateTime_); }
/// <summary> /// Чтение месячных срезов /// </summary> /// <param name="month">Младшая тетрада - месяц 0h…Bh (0 -январь … Bh - декабрь); 0Fh – текущий месяц</param> /// <returns>Считанный массив. В случае ошибки - массив с одним элементом (кодом ошибки error_type) = { (int)Rxmes_.err };</returns> public int[] CallAccumulEnergy_activ_month(byte month) { byte[] mes = { address[0], address[1], address[2], address[3], 0x32, month }; RXmes Rxmes_ = SendCmd(mes); if ((Rxmes_.err == error_type.none) || (Rxmes_.buff.Length > 7)) { int[] intBuf = new int[(Rxmes_.buff.Length - 5 - 2) / 4]; return(energy_byteArr_to_IntArr(Rxmes_.buff)); } int[] z = { (int)Rxmes_.err }; return(z); }
public string ReadLocationMeter() { byte[] mes = { address, 0x08, 0x0B }; RXmes Rxmes_ = SendCmd(mes); if ((testAnswer(Rxmes_) == 0) && (Rxmes_.buff.Length > 5)) { byte[] arr = { Rxmes_.buff[1], Rxmes_.buff[2], Rxmes_.buff[3], Rxmes_.buff[4] }; if ((arr[0] + arr[1] + arr[2] + arr[3]) == 0) { return("none"); } return(System.Text.Encoding.ASCII.GetString(arr));; } return("err"); }
/// <summary> /// Установка внутренних часов и календаря счетчика /// </summary> /// <param name="dt">Устанавливаемое время</param> /// <returns></returns> public error_type SetTime(DateTime dt) { // 5 6 7 8 9 10 11 //dow-hh-mm-ss-dd-mon-yy byte dow = (byte)byte_to_BCD((byte)dt.DayOfWeek); byte hh = (byte)byte_to_BCD((byte)dt.Hour); byte mm = (byte)byte_to_BCD((byte)dt.Minute); byte ss = (byte)byte_to_BCD((byte)dt.Second); byte dd = (byte)byte_to_BCD((byte)dt.Day); byte mon = (byte)byte_to_BCD((byte)dt.Month); byte yy = (byte)byte_to_BCD((byte)(dt.Year - dt.Year / 100 * 100)); byte[] mes = { address[0], address[1], address[2], address[3], 0x02, dow, hh, mm, ss, dd, mon, yy }; RXmes Rxmes_ = SendCmd(mes); return(Rxmes_.err); }
public error_type SetLocationMeter(string str) { //str = str; byte[] bytes = new byte[str.Length + 3]; bytes[0] = address; bytes[1] = 0x03; bytes[2] = 0x22; int i = 2; byte[] charr = Encoding.ASCII.GetBytes(str); foreach (char ch in charr) { i++; bytes[i] = charr[i - 3]; } RXmes Rxmes_ = SendCmd(bytes); return(testAnswer(Rxmes_)); }
/// <summary> /// Чтение внутренних часов и календаря счетчика /// </summary> /// <returns></returns> public elecMeterDateTime CallDateTime() { byte[] mes = { address[0], address[1], address[2], address[3], 0x21 }; RXmes Rxmes_ = SendCmd(mes); elecMeterDateTime date_struct = new elecMeterDateTime(); if (Rxmes_.err == error_type.none) { for (int i = 0; i < Rxmes_.buff.Length; i++) { Rxmes_.buff[i] = (byte)BCD_to_byte(Rxmes_.buff[i]); } // 5 6 7 8 9 10 11 //dow-hh-mm-ss-dd-mon-yy date_struct.dt = new DateTime(Rxmes_.buff[11] + 2000, Rxmes_.buff[10], Rxmes_.buff[9], Rxmes_.buff[6], Rxmes_.buff[7], Rxmes_.buff[8]); date_struct.day = Rxmes_.buff[5]; } date_struct.error = Rxmes_.err; return(date_struct); }