/// <summary> converts a part (telegram head) of the byte array into C# types for further usage </summary> /// <param name="theData"> the byte array </param> /// <param name="length"> the length of the telegram </param> /// <param name="offset"> offset needed to convert the data </param> /// <returns> object of type "TelegramHead" for further usage (displaying on the UI) </returns> private TelegramHead readOutTelegramHead(S7DataConverter theData, int length, ref int offset) { // read telegram-header UInt16 telID = 0; UInt16 telStatus = 0; UInt32 telNumber = 0; DateTime telSendTime = new DateTime(2004, 12, 3); Int16 telNumberRecords = 0; offset = theData.GetValue(offset, S7Types.WORD, ref telID); offset = theData.GetValue(offset, S7Types.WORD, ref telStatus); offset = theData.GetValue(offset, S7Types.DWORD, ref telNumber); offset = theData.GetValue(offset, S7Types.DATE_AND_TIME, ref telSendTime); offset = theData.GetValue(offset, S7Types.INT, ref telNumberRecords); return(new TelegramHead(length, telID, telStatus, telNumber, telSendTime, telNumberRecords)); }
/// <summary> sets the value delivered from ondatachange </summary> /// <param name="theValue"> the value (must be byte array) </param> /// <exception cref="InvalidCastException"> if the value cannot be converted into a byte array </exception> /// <remarks> NOTES: /// - this methods measures the time for converting and saving to DB /// - it is recommended to call this method asynchronously, because saving to DB may take several seconds </remarks> public void setOPCParam(object theValue) { TelegramHead telHead = null; MeasuredHead measHeadVisu = null; MeasuredData measDataVisu = null; // Take time for converting StopWatch convStopWatch = new StopWatch(TimerType.PerformanceCounter); convStopWatch.Scale = 1000.0; convStopWatch.Start(); // Take time for saving StopWatch saveStopWatch = new StopWatch(TimerType.PerformanceCounter); saveStopWatch.Scale = 1000.0; // Convert data S7DataConverter theData; byte[] data = null; try { data = (byte[])theValue; theData = new S7DataConverter(data, true, true); } catch (InvalidCastException ex) { // forward the exception throw ex; } int offset = 0; // read telegram-header telHead = readOutTelegramHead(theData, data.Length, ref offset); // read out data readOutData(theData, telHead.telNumberRecords, ref offset, out measHeadVisu, out measDataVisu); convStopWatch.Stop(); // Now save update the database try { saveStopWatch.Start(); int idx = (int)m_ActiveDB; if (idx != 0) { ((DBInterface)(m_dataBases[idx])).Insert(); } } catch (Exception ex) { throw ex; } finally { saveStopWatch.Stop(); // Fill the data for visualization DataToVisualize dataToVisu = new DataToVisualize(telHead, measHeadVisu, measDataVisu, convStopWatch.Time, saveStopWatch.Time); // fire the event, that saving is completed OnBRCVOccured(this, dataToVisu); } }
/// <summary> converts a part (measured data) of the byte array into C# types for further usage </summary> /// <param name="theData"> the byte array </param> /// <param name="telNumberRecords"> the number of records (delivered via the telegram head) </param> /// <param name="offset"> offset needed to convert the data </param> /// <param name="measHeadVisu"> the head data for visualization </param> /// <param name="measDataVisu"> the measured data for visualization </param> /// <remarks> NOTE: this method also fills the data into the meant (transient) DB; the insertion of the data /// into the persistent storage has to be done in calling function! </remarks> private void readOutData(S7DataConverter theData, int telNumberRecords, ref int offset, out MeasuredHead measHeadVisu, out MeasuredData measDataVisu) { Int16 headDataH_ID = 0; DateTime headDataMeasureTime = new DateTime(2004, 12, 3); float headDataPressure = 0; float headDataEnergy = 0; string headDataDescription = ""; Int16 dataMeasurepointIndex = 0; float dataTemperature = 0; float dataPressure = 0; float dataFlow = 0; float dataHumidity = 0; string dataDescription = ""; MeasuredHead measHead = null; MeasuredData measData = null; measHeadVisu = null; measDataVisu = null; for (int i = 0; i < telNumberRecords; i++) { // read data-header offset = theData.GetValue(offset, S7Types.INT, ref headDataH_ID); offset = theData.GetValue(offset, S7Types.DATE_AND_TIME, ref headDataMeasureTime); offset = theData.GetValue(offset, S7Types.REAL, ref headDataPressure); offset = theData.GetValue(offset, S7Types.REAL, ref headDataEnergy); offset = theData.GetValue(offset, S7Types.STRING, ref headDataDescription); // adjust offset manually! The string has 10 characters. offset += 10; System.Int32 h_idx = 0; measHead = new MeasuredHead(headDataH_ID, headDataMeasureTime, headDataPressure, headDataEnergy, headDataDescription); // Now add the row h_idx = addRowsHeater(measHead); // read measured data // there are 8 measurementpoints for (int j = 0; j < 8; j++) { offset = theData.GetValue(offset, S7Types.INT, ref dataMeasurepointIndex); offset = theData.GetValue(offset, S7Types.REAL, ref dataTemperature); offset = theData.GetValue(offset, S7Types.REAL, ref dataPressure); offset = theData.GetValue(offset, S7Types.REAL, ref dataFlow); offset = theData.GetValue(offset, S7Types.REAL, ref dataHumidity); offset = theData.GetValue(offset, S7Types.STRING, ref dataDescription); // adjust offset manually! The string has 10 characters. offset += 10; measData = new MeasuredData(dataMeasurepointIndex, dataTemperature, dataPressure, dataFlow, dataHumidity, dataDescription); // all data is collected -> add the row addRowsMeasure(h_idx, measData); if (i == 0 && j == 0) { measHeadVisu = measHead.Clone(); measDataVisu = measData.Clone(); } } } }