/// <summary> /// Decodes the specified object and converts it to a tag data. /// </summary> private SrezTableLight.CnlData DecodeTag(object val, out TagType tagType) { try { if (val == DBNull.Value) { tagType = TagType.Number; return(SrezTableLight.CnlData.Empty); } else if (val is string) { tagType = TagType.String; return(new SrezTableLight.CnlData(ScadaUtils.EncodeAscii((string)val), BaseValues.CnlStatuses.Defined)); } else if (val is DateTime) { tagType = TagType.DateTime; return(new SrezTableLight.CnlData(ScadaUtils.EncodeDateTime((DateTime)val), BaseValues.CnlStatuses.Defined)); } else { tagType = TagType.Number; return(new SrezTableLight.CnlData(Convert.ToDouble(val), BaseValues.CnlStatuses.Defined)); } } catch { tagType = TagType.Number; return(SrezTableLight.CnlData.Empty); } }
/// <summary> /// Decodes the received tag value and returns the tag type. /// </summary> private double DecodeItemVal(object val, out TagType tagType) { try { if (val is string) { tagType = TagType.String; return(ScadaUtils.EncodeAscii((string)val)); } else if (val is DateTime) { tagType = TagType.DateTime; return(ScadaUtils.EncodeDateTime((DateTime)val)); } else { tagType = TagType.Number; return(Convert.ToDouble(val)); } } catch (Exception ex) { WriteToLog((Localization.UseRussian ? "Ошибка при декодировании элемента: " : "Error decoding item: ") + ex); tagType = TagType.Number; return(0.0); } }
/// <summary> /// Decodes the received array and returns the tag type. /// </summary> private double[] DecodeArray(object val, int len, out TagType tagType) { double[] outArr = new double[len]; tagType = TagType.Number; try { // get the type of the 1st element Array inArr = (Array)val; if (inArr.Length > 0) { object firstItem = inArr.GetValue(0); if (firstItem is string) { tagType = TagType.String; } else if (firstItem is DateTime) { tagType = TagType.DateTime; } } // decode array elements for (int i = 0, n = Math.Min(inArr.Length, len); i < n; i++) { object inVal = inArr.GetValue(i); double outVal; switch (tagType) { case TagType.String: outVal = ScadaUtils.EncodeAscii((string)inVal); break; case TagType.DateTime: outVal = ScadaUtils.EncodeDateTime((DateTime)inVal); break; default: outVal = Convert.ToDouble(inVal); break; } outArr[i] = outVal; } } catch (Exception ex) { WriteToLog((Localization.UseRussian ? "Ошибка при декодировании массива: " : "Error decoding array: ") + ex); } return(outArr); }
/// <summary> /// Декодировать данные переменной SNMP /// </summary> private bool DecodeVarData(ISnmpData snmpData, bool isBits, out SrezTableLight.CnlData tagData, out bool isString) { tagData = SrezTableLight.CnlData.Empty; isString = false; if (snmpData == null) { return(false); } else if (isBits) { if (snmpData.TypeCode == SnmpType.OctetString) { // получение значения типа BITS: последний полученный байт строки - младший байт значения тега byte[] snmpRaw = ((OctetString)snmpData).GetRaw(); byte[] tagRaw = new byte[8]; for (int i = 0, j = snmpRaw.Length - 1; i < 8; i++, j--) { tagRaw[i] = j >= 0 ? snmpRaw[j] : (byte)0; } tagData = new SrezTableLight.CnlData(BitConverter.ToUInt64(tagRaw, 0), 1); return(true); } else { return(false); } } else { try { switch (snmpData.TypeCode) { case SnmpType.Integer32: tagData = new SrezTableLight.CnlData(((Integer32)snmpData).ToInt32(), 1); return(true); case SnmpType.Counter32: tagData = new SrezTableLight.CnlData(((Counter32)snmpData).ToUInt32(), 1); return(true); case SnmpType.Counter64: tagData = new SrezTableLight.CnlData(((Counter64)snmpData).ToUInt64(), 1); return(true); case SnmpType.Gauge32: tagData = new SrezTableLight.CnlData(((Gauge32)snmpData).ToUInt32(), 1); return(true); case SnmpType.TimeTicks: tagData = new SrezTableLight.CnlData(((TimeTicks)snmpData).ToUInt32(), 1); return(true); case SnmpType.OctetString: string s = snmpData.ToString().Trim(); double val; if (s.Equals("true", StringComparison.OrdinalIgnoreCase)) { tagData = new SrezTableLight.CnlData(1.0, 1); return(true); } else if (s.Equals("false", StringComparison.OrdinalIgnoreCase)) { tagData = new SrezTableLight.CnlData(0.0, 1); return(true); } else if (double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out val)) { tagData = new SrezTableLight.CnlData(val, 1); return(true); } else { // преобразование 8 байт строки в число double tagData = new SrezTableLight.CnlData(ScadaUtils.EncodeAscii(s), 1); isString = true; return(true); } default: return(false); } } catch (Exception ex) { WriteToLog(string.Format(Localization.UseRussian ? "Ошибка при расшифровке данных \"{0}\" типа {1}: {2}" : "Error decoding data \"{0}\" of type {1}: {2}", snmpData.ToString(), snmpData.TypeCode.ToString(), ex.Message)); return(false); } } }
/// <summary> /// Сеанс опроса основного КП /// </summary> private void PrimarySession() { Connection.WriteToLog = WriteToLog; Connection.NewLine = NewLine; int tryNum; // отключение эхо if (WorkState != WorkStates.Normal) { lastCommSucc = false; tryNum = 0; while (RequestNeeded(ref tryNum)) { WriteToLog(Localization.UseRussian ? "Отключение эхо" : "Set echo off"); Connection.WriteLine("ATE0"); Connection.ReadLines(ReqParams.Timeout, OkStopCond, out lastCommSucc); FinishRequest(); tryNum++; } } // сброс вызова if (lastCommSucc) { lastCommSucc = false; tryNum = 0; while (RequestNeeded(ref tryNum)) { WriteToLog(Localization.UseRussian ? "Сброс вызова" : "Drop call"); Connection.WriteLine("ATH" /*"AT+CHUP"*/); Connection.ReadLines(ReqParams.Timeout, OkStopCond, out lastCommSucc); FinishRequest(); tryNum++; } } // обработка и удаление сообщений, полученных ранее int eventCnt = 0; // количество созданных событий if (lastCommSucc) { foreach (Message msg in messageList) { // обработка сообщения, если оно не обработано другими КП try { object[] msgObjArr = msg.Reference; if (!(bool)msgObjArr[5] /*сообщение не обработано*/ && (int)msgObjArr[1] <= 1 /*принятое сообщение*/) { // запись события WriteEvent(msg.TimeStamp, msg.Phone, msg.Text, ref eventCnt); msgObjArr[5] = true; // TEST ---------------------- string phone = msg.Phone; phone = phone.Replace("+", ""); double dPhone; SetCurData(2, ScadaUtils.EncodeAscii(msg.Text), 1); if (double.TryParse(phone, NumberStyles.Any, CultureInfo.InvariantCulture, out dPhone)) { SetCurData(3, dPhone, 1); } else { InvalidateCurData(3, 1); } // TEST --------------------------- } } catch { WriteToLog((Localization.UseRussian ? "Ошибка при обработке сообщения " : "Error processing message ") + msg.Index); } // удаление сообщений из памяти GSM-терминала bool deleteComplete = false; tryNum = 0; while (tryNum < ReqTriesCnt && !deleteComplete && !Terminated) { WriteToLog((Localization.UseRussian ? "Удаление сообщения " : "Delete message ") + msg.Index); Connection.WriteLine("AT+CMGD=" + msg.Index); Connection.ReadLines(ReqParams.Timeout, OkStopCond, out deleteComplete); FinishRequest(); tryNum++; } lastCommSucc = lastCommSucc && deleteComplete; } messageList.Clear(); GetMessageObjList().Clear(); } IncEventCount(eventCnt); if (lastCommSucc) { WriteToLog((Localization.UseRussian ? "Количество полученных сообщений: " : "Received message count: ") + eventCnt); } // запрос списка сообщений if (lastCommSucc) { lastCommSucc = false; tryNum = 0; while (RequestNeeded(ref tryNum)) { WriteToLog(Localization.UseRussian ? "Запрос списка сообщений" : "Request message list"); Connection.WriteLine("AT+CMGL=4"); List <string> inData = Connection.ReadLines(ReqParams.Timeout, OkStopCond, out lastCommSucc); // расшифровка сообщений if (lastCommSucc) { string logMsg; if (!FillMessageList(inData, out logMsg)) { lastCommSucc = false; } if (logMsg != "") { WriteToLog(logMsg); } } FinishRequest(); tryNum++; } // запись сообщений в общие свойства линии связи List <object[]> msgObjList = GetMessageObjList(); foreach (Message msg in messageList) { object[] msgObjArr = ConvertMessage(msg); msg.Reference = msgObjArr; msgObjList.Add(msgObjArr); } } // определение наличия связи double newVal = lastCommSucc ? 1.0 : -1.0; SetCurData(0, newVal, 1); }