// Constructors public RequestElectricityMeter() { byte[] data = new byte[30]; int checksum = 0; m_reqStrm = new MemoryStream(); System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); byte[] dataHeaderBin = { (byte)BravaCodes.Tasks.Request, (byte)BravaCodes.Functions.ElectricityMeter, (byte)BravaCodes.ElectricityMeterRecords.CurrentConsumptionDelivered, (byte)BravaConstants.AllRecords }; checksum += BravaUtilities.GetCheckSum(dataHeaderBin, 0, dataHeaderBin.Length - 1); byte[] dataHeaderAsc = enc.GetBytes(BravaUtilities.ByteArrayToHexString(dataHeaderBin)); byte[] dataPayloadBin = new byte[8]; Array.Copy(enc.GetBytes(ZIRODEConstants.ZIRODECODE1), dataPayloadBin, 4); Array.Copy(BitConverter.GetBytes(BravaUtilities.GetUTCTimeStamp()), 0, dataPayloadBin, 4, 4); checksum += BravaUtilities.GetCheckSum(dataPayloadBin, 0, dataPayloadBin.Length - 1); byte[] dataPayloadAsc = enc.GetBytes(BravaUtilities.ByteArrayToHexString(dataPayloadBin)); byte[] checksumAsc = enc.GetBytes(BravaUtilities.ByteArrayToHexString(BitConverter.GetBytes((byte)checksum))); // Concatenate all blocks to output buffer. System.Buffer.BlockCopy(dataHeaderAsc, 0, data, 1, 8); System.Buffer.BlockCopy(dataPayloadAsc, 0, data, 10, 16); System.Buffer.BlockCopy(checksumAsc, 0, data, 27, 2); data[0] = 0x01; data[9] = 0x02; data[26] = 0x03; data[29] = 0x04; m_reqStrm.Write(data, 0, data.Length); }
// Methods /// <summary> /// Parses Result Stream from PM9 system. /// </summary> public void ParseResultStream() { // Copy response stream into a more versatile memory stream. byte[] bufferBytes = new byte[m_resStrm.Length]; m_resStrm.Seek(0, SeekOrigin.Begin); m_resStrm.Read(bufferBytes, 0, (int)m_resStrm.Length); MemoryStream resMemStr = new MemoryStream(); int bytesRead; byte[] headerbytes = null; byte[] recordSetHeaderBytes = null; ArrayList recordSetBytes = new ArrayList(); #region Test Debug Code //MemoryStream resMemStr = new MemoryStream(); //System.Xml.XmlDocument ResultXML; //FileStream fs = File.Open(@"C:\Buffer\Reply_PM9_1.bin", FileMode.Open, FileAccess.Read); //bufferBytes = new byte[fs.Length]; //fs.Seek(0, SeekOrigin.Begin); //bytesRead = fs.Read(bufferBytes, 0, (int)fs.Length); //fs.Close(); #endregion #region Deserialise // Now we have a byte array of the stream with tranmission markers and data in ASCII hex. // Now validate transmission Markers are all there. // quick and simple method... not optimal ram usage ... int indexSOH = Array.IndexOf(bufferBytes, (byte)0x01); int indexSTX = Array.IndexOf(bufferBytes, (byte)0x02); int indexEOT = Array.IndexOf(bufferBytes, (byte)0x04); int indexCR1 = Array.IndexOf(bufferBytes, (byte)0x0d); // check existence and relative position. if ((indexSOH >= 0) && (indexSTX == indexSOH + 9) && (indexCR1 > indexSTX) && (indexEOT > indexCR1)) { // markers exist and are correct in relation to each other. // Remove markers and de-serialise into seperate binary arrays. // get different sections in binary; headerbytes = BravaUtilities.HexBytesToByteArray(bufferBytes, indexSOH + 1, 4); recordSetHeaderBytes = BravaUtilities.HexBytesToByteArray(bufferBytes, indexSTX + 1, (indexCR1 - 1 - indexSTX) / 2); // Check if correct transaction. if (headerbytes[0] == 0x03 && headerbytes[1] == 0x01 && headerbytes[2] == 0x01) { int numRecords = headerbytes[3]; int recordStart = indexCR1 + 1; // find next record end marker int recordEnd; for (int n = 0; n < numRecords; n++) { recordEnd = Array.IndexOf(bufferBytes, (byte)0x0d, recordStart); byte[] recordBytes = BravaUtilities.HexBytesToByteArray(bufferBytes, recordStart, (recordEnd - recordStart) / 2); recordSetBytes.Add(recordBytes); recordStart = recordEnd + 1; } } } #endregion #region Parse To XML // Now parse the different byte sections into an XML document. XmlTextWriter writer = new XmlTextWriter(resMemStr, Encoding.UTF8); writer.Formatting = Formatting.Indented; writer.WriteStartDocument(); writer.WriteStartElement("Transaction", "BravaSystem.Communication"); writer.WriteStartElement("Response"); writer.WriteStartElement("Header"); writer.WriteAttributeString("Task", XmlConvert.ToString(headerbytes[0])); writer.WriteAttributeString("Function", XmlConvert.ToString(headerbytes[1])); writer.WriteAttributeString("RecordType", XmlConvert.ToString(headerbytes[2])); writer.WriteAttributeString("RecordCount", XmlConvert.ToString(headerbytes[3])); writer.WriteEndElement(); // End "Header" writer.WriteStartElement("Data"); writer.WriteAttributeString("RecordCount", XmlConvert.ToString(headerbytes[3])); writer.WriteAttributeString("UTCTime", BravaUtilities.GetUTCTime(BitConverter.ToUInt32(recordSetHeaderBytes, 4)).ToString()); // Now Loop through all the records. foreach (byte[] recordBytes in recordSetBytes) { writer.WriteStartElement("Record"); writer.WriteAttributeString("RecordType", XmlConvert.ToString(recordBytes[0])); writer.WriteAttributeString("ZBNode", XmlConvert.ToString(recordBytes[1])); writer.WriteAttributeString("RSSI", XmlConvert.ToString(recordBytes[2])); writer.WriteAttributeString("DeviceID", XmlConvert.ToString(recordBytes[3])); writer.WriteAttributeString("UnitSerialNumber", XmlConvert.ToString(BitConverter.ToUInt32(recordBytes, 4))); writer.WriteAttributeString("Reading1", XmlConvert.ToString(BitConverter.ToUInt32(recordBytes, 8))); writer.WriteAttributeString("TimeStamp1", XmlConvert.ToString(BitConverter.ToUInt16(recordBytes, 12))); writer.WriteAttributeString("Reading2", XmlConvert.ToString(BitConverter.ToUInt32(recordBytes, 14))); writer.WriteAttributeString("TimeStamp2", XmlConvert.ToString(BitConverter.ToUInt16(recordBytes, 18))); writer.WriteAttributeString("Reading3", XmlConvert.ToString(BitConverter.ToUInt32(recordBytes, 20))); writer.WriteAttributeString("TimeStamp3", XmlConvert.ToString(BitConverter.ToUInt16(recordBytes, 24))); writer.WriteAttributeString("Reading4", XmlConvert.ToString(BitConverter.ToUInt32(recordBytes, 26))); writer.WriteAttributeString("TimeStamp4", XmlConvert.ToString(BitConverter.ToUInt16(recordBytes, 30))); writer.WriteEndElement(); // End "Record" } writer.WriteEndElement(); // End "Data" writer.WriteEndElement(); // End "Response" writer.WriteEndElement(); // End "Transaction" writer.WriteEndDocument(); writer.Flush(); #endregion ResultXML = new XmlDocument(); resMemStr.Seek(0, SeekOrigin.Begin); ResultXML.Load(resMemStr); writer.Close(); // DEBUG: System.Diagnostics.Debug.WriteLine(ResultXML.OuterXml); }