public void Disconnect() { try { UpdateStatus(DeviceState.Disconnecting); if (KeepAlive.Enabled) { KeepAlive.Stop(); } if (m_Communicator.Media.IsOpen) { m_Communicator.ReadDLMSPacket(m_Communicator.DisconnectRequest(), 1); } } catch (Exception Ex) { //Do not show error occurred in disconnect. Write error only to the log file. GXLogWriter.WriteLog(Ex.Message); } finally { if (m_Communicator.Media != null) { m_Communicator.Media.Close(); } UpdateStatus(DeviceState.Initialized); } }
public byte[] Read(GXDLMSObject it, int attributeOrdinal) { lastTransaction = DateTime.Now; byte[] tmp = client.Read(it, attributeOrdinal)[0]; GXLogWriter.WriteLog(string.Format("Reading object {0} from interface {1}", it.LogicalName, it.ObjectType), tmp); return(tmp); }
public void Disconnect() { try { if (KeepAlive.Enabled) { KeepAlive.Stop(); } if (Comm.media.IsOpen && m_Status != DeviceState.Disconnecting) { if (Comm.media is IGXMedia2) { if (((IGXMedia2)Comm.media).AsyncWaitHandle != null) { ((IGXMedia2)Comm.media).AsyncWaitHandle.Set(); } } UpdateStatus(DeviceState.Disconnecting); communicator.Disconnect(); } else { Comm.media.Close(); } } catch (Exception Ex) { //Do not show error occurred in disconnect. Write error only to the log file. GXLogWriter.WriteLog(Ex.Message); } finally { UpdateStatus(DeviceState.Initialized); } }
public void KeepAlive() { GXReplyData reply = new GXReplyData(); byte[] data = client.GetKeepAlive(); GXLogWriter.WriteLog("Send Keep Alive", data); ReadDLMSPacket(data, reply); }
public void KeepAlive() { byte[] allData = null, reply = null; byte[] data = m_Cosem.GetKeepAlive(); GXLogWriter.WriteLog("Send Keep Alive", data); reply = ReadDLMSPacket(data); m_Cosem.GetDataFromPacket(reply, ref allData); }
public byte[] Read(object data, ObjectType type, int AttributeOrdinal) { LastTransaction = DateTime.Now; if (data is GXDLMSObject) { GXDLMSObject obj = data as GXDLMSObject; data = obj.Name; } byte[] tmp = m_Cosem.Read(data, type, AttributeOrdinal)[0]; GXLogWriter.WriteLog(string.Format("Reading object {0} from interface {1}", data.ToString(), type.ToString()), tmp); return(tmp); }
/// <summary> /// Read data block from the device. /// </summary> /// <param name="data">data to send</param> /// <param name="text">Progress text.</param> /// <param name="multiplier"></param> /// <returns>Received data.</returns> internal void ReadDataBlock(byte[] data, string text, int multiplier, GXReplyData reply) { lastTransaction = DateTime.Now; GXLogWriter.WriteLog(text, data); if (parent.OnTrace != null) { parent.OnTrace(parent, text + "\r\n<-\t" + DateTime.Now.ToLongTimeString(), data, 0, LogFile); } ReadDLMSPacket(data, reply); if (OnDataReceived != null) { OnDataReceived(this, reply); } if (reply.IsMoreData) { if (reply.TotalCount != 1) { NotifyProgress(text, 1, multiplier * reply.TotalCount); } while (reply.IsMoreData) { data = client.ReceiverReady(reply.MoreData); if ((reply.MoreData & RequestTypes.Frame) != 0) { GXLogWriter.WriteLog("Get next frame."); } else { GXLogWriter.WriteLog("Get Next Data block."); } if (parent.OnTrace != null) { parent.OnTrace(parent, "<-\t" + DateTime.Now.ToLongTimeString(), data, 0, LogFile); } GXLogWriter.WriteLog(text, data); ReadDLMSPacket(data, reply); if (OnDataReceived != null) { OnDataReceived(this, reply); } if (reply.TotalCount != 1) { NotifyProgress(text, reply.Count, multiplier * reply.TotalCount); } } } }
public GXDLMSObjectCollection GetObjects() { GXLogWriter.WriteLog("--- Collecting objects. ---"); byte[] allData; try { NotifyProgress("Collecting objects", 0, 1); allData = ReadDataBlock(m_Cosem.GetObjectsRequest(), "Collecting objects"); } catch (Exception Ex) { throw new Exception("GetObjects failed. " + Ex.Message); } GXDLMSObjectCollection objs = m_Cosem.ParseObjects(allData, true); NotifyProgress("Collecting objects", objs.Count, objs.Count); GXLogWriter.WriteLog("--- Collecting " + objs.Count.ToString() + " objects. ---"); return(objs); }
/// <summary> /// Read data block from the device. /// </summary> /// <param name="data">data to send</param> /// <param name="text">Progress text.</param> /// <param name="multiplier"></param> /// <returns>Received data.</returns> internal void ReadDataBlock(byte[] data, string text, int multiplier, GXReplyData reply) { if (parent.InactivityMode == InactivityMode.ReopenActive && media is GXSerial && DateTime.Now.Subtract(connectionStartTime).TotalSeconds > 40) { parent.Disconnect(); parent.InitializeConnection(); } GXLogWriter.WriteLog(text, data); ReadDLMSPacket(data, reply); if (OnDataReceived != null) { OnDataReceived(this, reply); } if (reply.IsMoreData) { if (reply.TotalCount != 1) { NotifyProgress(text, 1, multiplier * reply.TotalCount); } while (reply.IsMoreData) { data = client.ReceiverReady(reply.MoreData); if ((reply.MoreData & RequestTypes.Frame) != 0) { GXLogWriter.WriteLog("Get next frame: ", data); } else { GXLogWriter.WriteLog("Get Next Data block: ", data); } ReadDLMSPacket(data, reply); if (OnDataReceived != null) { OnDataReceived(this, reply); } if (reply.TotalCount != 1) { NotifyProgress(text, reply.Count, multiplier * reply.TotalCount); } } } }
public GXDLMSObjectCollection GetObjects() { GXLogWriter.WriteLog("--- Collecting objects. ---"); GXReplyData reply = new GXReplyData() { }; try { ReadDataBlock(client.GetObjectsRequest(), "Collecting objects", 3, reply); } catch (Exception Ex) { throw new Exception("GetObjects failed. " + Ex.Message); } GXDLMSObjectCollection objs = client.ParseObjects(reply.Data, true); GXLogWriter.WriteLog("--- Collecting " + objs.Count.ToString() + " objects. ---"); return(objs); }
public void Disconnect() { try { UpdateStatus(DeviceState.Disconnecting); if (KeepAlive.Enabled) { KeepAlive.Stop(); } communicator.Disconnect(); } catch (Exception Ex) { //Do not show error occurred in disconnect. Write error only to the log file. GXLogWriter.WriteLog(Ex.Message); } finally { UpdateStatus(DeviceState.Initialized); } }
/// <summary> /// Read data block from the device. /// </summary> /// <param name="data">data to send</param> /// <param name="text">Progress text.</param> /// <param name="multiplier"></param> /// <returns>Received data.</returns> internal byte[] ReadDataBlock(byte[] data, string text, double multiplier) { if (Parent.InactivityMode == InactivityMode.ReopenActive && Media is GXSerial && DateTime.Now.Subtract(ConnectionStartTime).TotalSeconds > 40) { Parent.Disconnect(); Parent.InitializeConnection(); } GXLogWriter.WriteLog(text, data); byte[] reply = ReadDLMSPacket(data); byte[] allData = null; RequestTypes moredata = m_Cosem.GetDataFromPacket(reply, ref allData); if (OnDataReceived != null) { OnDataReceived(this, (byte[])allData); } if ((moredata & (RequestTypes.Frame | RequestTypes.DataBlock)) != 0) { int maxProgress = m_Cosem.GetMaxProgressStatus(allData); NotifyProgress(text, 1, maxProgress); while (moredata != 0) { while ((moredata & RequestTypes.Frame) != 0) { data = m_Cosem.ReceiverReady(RequestTypes.Frame); GXLogWriter.WriteLog("Get next frame: ", (byte[])data); reply = ReadDLMSPacket(data); RequestTypes tmp = m_Cosem.GetDataFromPacket(reply, ref allData); if (OnDataReceived != null) { OnDataReceived(this, (byte[])allData); } //If this was last frame. if ((tmp & RequestTypes.Frame) == 0) { moredata &= ~RequestTypes.Frame; break; } int current = m_Cosem.GetCurrentProgressStatus(allData); //TODO: System.Diagnostics.Debug.Assert(!(current == maxProgress && moredata != RequestTypes.None)); NotifyProgress(text, (int)(multiplier * current), maxProgress); } if (Parent.InactivityMode == InactivityMode.ReopenActive && Media is GXSerial && DateTime.Now.Subtract(ConnectionStartTime).TotalSeconds > 40) { Parent.Disconnect(); Parent.InitializeConnection(); } if ((moredata & RequestTypes.DataBlock) != 0) { //Send Receiver Ready. data = m_Cosem.ReceiverReady(RequestTypes.DataBlock); GXLogWriter.WriteLog("Get Next Data block: ", (byte[])data); reply = ReadDLMSPacket(data); moredata = m_Cosem.GetDataFromPacket(reply, ref allData); if (OnDataReceived != null) { OnDataReceived(this, (byte[])allData); } int current = m_Cosem.GetCurrentProgressStatus(allData); //TODO: System.Diagnostics.Debug.Assert(!(current == maxProgress && moredata != RequestTypes.None)); NotifyProgress(text, (int)(multiplier * current), maxProgress); } } } return(allData); }
void InitializeIEC() { GXManufacturer manufacturer = this.Parent.Manufacturers.FindByIdentification(Parent.Manufacturer); if (manufacturer == null) { throw new Exception("Unknown manufacturer " + Parent.Manufacturer); } GXSerial serial = Media as GXSerial; byte Terminator = (byte)0x0A; if (serial != null && Parent.StartProtocol == StartProtocolType.IEC) { serial.BaudRate = 300; serial.DataBits = 7; serial.Parity = Parity.Even; serial.StopBits = StopBits.One; } Media.Open(); //Query device information. if (Media != null && Parent.StartProtocol == StartProtocolType.IEC) { string data = "/?!\r\n"; if (this.Parent.HDLCAddressing == HDLCAddressType.SerialNumber) { data = "/?" + this.Parent.PhysicalAddress + "!\r\n"; } GXLogWriter.WriteLog("HDLC sending:" + data); ReceiveParameters <string> p = new ReceiveParameters <string>() { AllData = false, Eop = Terminator, WaitTime = Parent.WaitTime * 1000 }; lock (Media.Synchronous) { Media.Send(data, null); if (!Media.Receive(p)) { //Try to move away from mode E. try { this.ReadDLMSPacket(this.DisconnectRequest(), 1); } catch (Exception ex) { } data = (char)0x01 + "B0" + (char)0x03 + "\r\n"; Media.Send(data, null); p.Count = 1; Media.Receive(p); data = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(data); throw new Exception(data); } //If echo is used. if (p.Reply == data) { p.Reply = null; if (!Media.Receive(p)) { //Try to move away from mode E. this.ReadDLMSPacket(this.DisconnectRequest(), 1); if (serial != null) { data = (char)0x01 + "B0" + (char)0x03 + "\r\n"; Media.Send(data, null); p.Count = 1; if (!Media.Receive(p)) { } serial.DtrEnable = serial.RtsEnable = false; serial.BaudRate = 9600; serial.DtrEnable = serial.RtsEnable = true; data = (char)0x01 + "B0" + (char)0x03 + "\r\n"; Media.Send(data, null); p.Count = 1; Media.Receive(p); } data = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(data); throw new Exception(data); } } } GXLogWriter.WriteLog("HDLC received: " + p.Reply); if (p.Reply[0] != '/') { p.WaitTime = 100; Media.Receive(p); throw new Exception("Invalid responce."); } string manufactureID = p.Reply.Substring(1, 3); UpdateManufactureSettings(manufactureID); char baudrate = p.Reply[4]; int BaudRate = 0; switch (baudrate) { case '0': BaudRate = 300; break; case '1': BaudRate = 600; break; case '2': BaudRate = 1200; break; case '3': BaudRate = 2400; break; case '4': BaudRate = 4800; break; case '5': BaudRate = 9600; break; case '6': BaudRate = 19200; break; default: throw new Exception("Unknown baud rate."); } GXLogWriter.WriteLog("BaudRate is : " + BaudRate.ToString()); //Send ACK //Send Protocol control character byte controlCharacter = (byte)'2';// "2" HDLC protocol procedure (Mode E) //Send Baud rate character //Mode control character byte ModeControlCharacter = (byte)'2';//"2" //(HDLC protocol procedure) (Binary mode) //Set mode E. byte[] arr = new byte[] { 0x06, controlCharacter, (byte)baudrate, ModeControlCharacter, 13, 10 }; GXLogWriter.WriteLog("Moving to mode E.", arr); lock (Media.Synchronous) { Media.Send(arr, null); System.Threading.Thread.Sleep(500); serial.BaudRate = BaudRate; p.Reply = null; p.WaitTime = 100; //Note! All meters do not echo this. Media.Receive(p); if (p.Reply != null) { GXLogWriter.WriteLog("Received: " + p.Reply); } serial.Close(); serial.DataBits = 8; serial.Parity = Parity.None; serial.StopBits = StopBits.One; serial.Open(); System.Threading.Thread.Sleep(500); } } }
public void InitializeConnection() { if (!string.IsNullOrEmpty(Parent.Manufacturer)) { UpdateManufactureSettings(Parent.Manufacturer); } if (Media is GXSerial) { GXLogWriter.WriteLog("Initializing serial connection."); InitSerial(); ConnectionStartTime = DateTime.Now; } else if (Media is GXNet) { GXLogWriter.WriteLog("Initializing Network connection."); InitNet(); //Some Electricity meters need some time before first message can be send. System.Threading.Thread.Sleep(500); } else if (Media is Gurux.Terminal.GXTerminal) { GXLogWriter.WriteLog("Initializing Terminal connection."); InitTerminal(); } else { throw new Exception("Unknown media type."); } try { byte[] data, reply = null; data = SNRMRequest(); if (data != null) { GXLogWriter.WriteLog("Send SNRM request.", data); reply = ReadDLMSPacket(data, 1); GXLogWriter.WriteLog("Parsing UA reply.", reply); //Has server accepted client. ParseUAResponse(reply); GXLogWriter.WriteLog("Parsing UA reply succeeded."); } //Generate AARQ request. //Split requests to multiple packets if needed. //If password is used all data might not fit to one packet. foreach (byte[] it in AARQRequest()) { GXLogWriter.WriteLog("Send AARQ request", it); reply = ReadDLMSPacket(it); } GXLogWriter.WriteLog("Parsing AARE reply", (byte[])reply); try { //Parse reply. ParseAAREResponse(reply); } catch (Exception Ex) { ReadDLMSPacket(DisconnectRequest(), 1); throw Ex; } //If authentication is required. if (m_Cosem.IsAuthenticationRequired) { foreach (byte[] it in m_Cosem.GetApplicationAssociationRequest()) { GXLogWriter.WriteLog("Authenticating", it); reply = ReadDLMSPacket(it); } m_Cosem.ParseApplicationAssociationResponse(reply); } } catch (Exception ex) { if (Media is GXSerial && Parent.StartProtocol == StartProtocolType.IEC) { ReceiveParameters <string> p = new ReceiveParameters <string>() { Eop = (byte)0xA, WaitTime = Parent.WaitTime * 1000 }; lock (Media.Synchronous) { string data = (char)0x01 + "B0" + (char)0x03 + "\r\n"; Media.Send(data, null); Media.Receive(p); } } throw ex; } GXLogWriter.WriteLog("Parsing AARE reply succeeded."); Parent.KeepAliveStart(); }
public byte[] DisconnectedModeRequest() { byte[] data = m_Cosem.DisconnectedModeRequest(); GXLogWriter.WriteLog("Disconnected Mode request", data); return(data); }
/// <summary> /// Read DLMS Data from the device. /// </summary> /// <remarks> /// If access is denied return null. /// </remarks> /// <param name="data">Data to send.</param> /// <returns>Received data.</returns> public byte[] ReadDLMSPacket(byte[] data, int tryCount) { if (data == null) { return(null); } object eop = (byte)0x7E; //In network connection terminator is not used. if (m_Cosem.InterfaceType == InterfaceType.Net && Media is GXNet && !Parent.UseRemoteSerial) { eop = null; } int pos = 0; bool succeeded = false; ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>() { AllData = false, Eop = eop, Count = 5, WaitTime = Parent.WaitTime * 1000, }; lock (Media.Synchronous) { if (data != null) { Media.Send(data, null); } while (!succeeded && pos != 3) { succeeded = Media.Receive(p); if (!succeeded) { //Try to read again... if (++pos != tryCount) { //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = 1; } System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); Media.Send(data, null); continue; } string err = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(err, p.Reply); throw new Exception(err); } } //Loop until whole COSEM packet is received. while (!m_Cosem.IsDLMSPacketComplete(p.Reply)) { //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = 1; } if (!Media.Receive(p)) { //Try to read again... if (++pos != tryCount) { System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); continue; } string err = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(err, p.Reply); throw new Exception(err); } } } GXLogWriter.WriteLog("Received data", p.Reply); object errors = m_Cosem.CheckReplyErrors(data, p.Reply); if (errors != null) { object[,] arr = (object[, ])errors; int error = (int)arr[0, 0]; if (error == -1) { //If data is reply to the previous packet sent. //This might happens sometimes. if (m_Cosem.IsPreviousPacket(data, p.Reply)) { return(ReadDLMSPacket(null)); } else { throw new Exception(arr[0, 1].ToString()); } } throw new GXDLMSException(error); } return(p.Reply); }
/// <summary> /// After UpdateObjects call objects can be read using Objects property. /// </summary> public void UpdateObjects() { try { GXDLMSObjectCollection objs = Comm.GetObjects(); objs.Tag = this; int pos = 0; foreach (GXDLMSObject it in objs) { ++pos; NotifyProgress(this, "Creating object " + it.LogicalName, pos, objs.Count); Objects.Add(it); } GXLogWriter.WriteLog("--- Created " + Objects.Count.ToString() + " objects. ---"); //Read registers units and scalers. int cnt = Objects.Count; if (!UseLogicalNameReferencing) { GXLogWriter.WriteLog("--- Reading Access rights. ---"); try { foreach (GXDLMSAssociationShortName sn in Objects.GetObjects(ObjectType.AssociationShortName)) { if (sn.Version > 1) { Comm.ReadValue(sn, 3); } } } catch (Exception ex) { GXLogWriter.WriteLog(ex.Message); } GXLogWriter.WriteLog("--- Reading Access rights end. ---"); } GXLogWriter.WriteLog("--- Reading scalers and units. ---"); this.OnProgress(this, "Reading scalers and units.", cnt + pos + 1, 3 * cnt); if ((Comm.client.NegotiatedConformance & Gurux.DLMS.Enums.Conformance.MultipleReferences) != 0) { List <KeyValuePair <GXDLMSObject, int> > list = new List <KeyValuePair <GXDLMSObject, int> >(); foreach (GXDLMSObject it in Objects) { if (it is GXDLMSRegister && (it.GetAccess(3) & AccessMode.Read) != 0) { list.Add(new KeyValuePair <GXDLMSObject, int>(it, 3)); } if (it is GXDLMSDemandRegister && (it.GetAccess(4) & AccessMode.Read) != 0) { list.Add(new KeyValuePair <GXDLMSObject, int>(it, 4)); } } if (list.Count != 0) { try { Comm.ReadList(list); } catch (Exception) { //Show error. } } } else { for (pos = 0; pos != cnt; ++pos) { GXDLMSObject it = Objects[pos]; if (it is GXDLMSRegister) { //Read scaler first. try { if ((it.GetAccess(3) & AccessMode.Read) != 0) { Comm.ReadValue(it, 3); } } catch (Exception ex) { GXLogWriter.WriteLog(ex.Message); it.SetAccess(3, AccessMode.NoAccess); if (ex is GXDLMSException) { continue; } throw ex; } } if (it is GXDLMSDemandRegister) { //Read scaler first. try { if ((it.GetAccess(4) & AccessMode.Read) != 0) { Comm.ReadValue(it, 4); } } catch (Exception ex) { GXLogWriter.WriteLog(ex.Message); UpdateError(it, 4, ex); if (ex is GXDLMSException) { continue; } throw ex; } //Read Period try { Comm.ReadValue(it, 8); } catch (Exception ex) { GXLogWriter.WriteLog(ex.Message); UpdateError(it, 8, ex); if (ex is GXDLMSException) { continue; } throw ex; } //Read number of periods try { Comm.ReadValue(it, 9); } catch (Exception ex) { GXLogWriter.WriteLog(ex.Message); UpdateError(it, 9, ex); if (ex is GXDLMSException) { continue; } throw ex; } } } } GXLogWriter.WriteLog("--- Reading scalers and units end. ---"); this.OnProgress(this, "Reading profile generic columns.", cnt, cnt); foreach (Gurux.DLMS.Objects.GXDLMSProfileGeneric it in objs.GetObjects(ObjectType.ProfileGeneric)) { ++pos; //Read Profile Generic Columns. try { NotifyProgress(this, "Get profile generic columns", (2 * cnt) + pos, 3 * objs.Count); UpdateColumns(it, Manufacturers.FindByIdentification(Manufacturer)); if (it.CaptureObjects == null || it.CaptureObjects.Count == 0) { continue; } } catch { GXLogWriter.WriteLog(string.Format("Failed to read Profile Generic {0} columns.", it.LogicalName)); continue; } } } finally { NotifyProgress(this, "", 0, 0); } }
byte[] ReleaseRequest() { byte[] data = client.ReleaseRequest()[0]; GXLogWriter.WriteLog("Release request", data); return(data); }
byte[] DisconnectRequest() { byte[] data = client.DisconnectRequest(); GXLogWriter.WriteLog("Disconnect request"); return(data); }
/// <summary> /// After UpdateObjects call objects can be read using Objects property. /// </summary> public void UpdateObjects() { try { GXDLMSObjectCollection objs = Comm.GetObjects(); objs.Tag = this; int pos = 0; foreach (GXDLMSObject it in objs) { //Profile Generic objects are added later. if (it.ObjectType == ObjectType.ProfileGeneric) { continue; } if (it.GetType() == typeof(GXDLMSObject)) { continue; } ++pos; NotifyProgress(this, "Creating object " + it.LogicalName, pos, objs.Count); m_Objects.Add(it); } GXLogWriter.WriteLog("--- Created " + m_Objects.Count.ToString() + " objects. ---"); int objPos = 0; //Read registers units and scalers. int cnt = Objects.Count; GXLogWriter.WriteLog("--- Reading scalers and units. ---"); for (pos = 0; pos != cnt; ++pos) { GXDLMSObject it = Objects[pos]; it.UpdateDefaultValueItems(); this.OnProgress(this, "Reading scalers and units.", pos + 1, cnt); if (it is GXDLMSRegister) { object data = it.ShortName; if (it.ShortName == 0) { data = it.LogicalName; } //Read scaler first. DataType type = DataType.None; try { data = Comm.ReadValue(data, it.ObjectType, 3, ref type); object tmp = GXHelpers.ConvertFromDLMS(data, DataType.None, DataType.None, false); //Actaris ACE 6000 is returning wrong value here. if (tmp is object[]) { object[] scalerUnit = (object[])tmp; ((GXDLMSRegister)it).Scaler = Math.Pow(10, Convert.ToInt32(scalerUnit.GetValue(0))); ((GXDLMSRegister)it).Unit = (Unit)Convert.ToInt32(scalerUnit.GetValue(1)); } } catch (Exception ex) { GXLogWriter.WriteLog(ex.Message); UpdateError(it, 3, ex); if (ex is GXDLMSException) { continue; } throw ex; } } if (it is GXDLMSDemandRegister) { object name = it.ShortName; object data; if (it.ShortName == 0) { name = it.LogicalName; } //Read scaler first. DataType type = DataType.None; byte attributeOrder = 4; try { data = Comm.ReadValue(name, it.ObjectType, attributeOrder, ref type); Array scalerUnit = (Array)GXHelpers.ConvertFromDLMS(data, DataType.None, DataType.None, false); ((GXDLMSDemandRegister)it).Scaler = Math.Pow(10, Convert.ToInt32(scalerUnit.GetValue(0))); ((GXDLMSDemandRegister)it).Unit = (Unit)Convert.ToInt32(scalerUnit.GetValue(1)); //Read Period data = Comm.ReadValue(name, it.ObjectType, 8, ref type); ((GXDLMSDemandRegister)it).Period = Convert.ToUInt64(data); //Read number of periods data = Comm.ReadValue(name, it.ObjectType, 9, ref type); ((GXDLMSDemandRegister)it).NumberOfPeriods = Convert.ToUInt32(data); } catch (Exception ex) { GXLogWriter.WriteLog(ex.Message); UpdateError(it, 3, ex); if (ex is GXDLMSException) { continue; } throw ex; } } } GXLogWriter.WriteLog("--- Reading scalers and units end. ---"); /* TODO: * if (!m.UseLogicalNameReferencing) * { * GXLogWriter.WriteLog("--- Reading Access rights. ---"); * try * { * foreach (GXDLMSAssociationShortName sn in dev.Objects.GetObjects(ObjectType.AssociationShortName)) * { * dev.Comm.Read(sn, 3); * } * } * catch (Exception ex) * { * GXLogWriter.WriteLog(ex.Message); * } * GXLogWriter.WriteLog("--- Reading Access rights end. ---"); * } * */ this.OnProgress(this, "Reading scalers and units.", cnt, cnt); foreach (Gurux.DLMS.Objects.GXDLMSProfileGeneric it in objs.GetObjects(ObjectType.ProfileGeneric)) { ++pos; NotifyProgress(this, "Creating object " + it.LogicalName, pos, objs.Count); //Read Profile Generic Columns. try { NotifyProgress(this, "Get profile generic columns", ++objPos, objs.Count); UpdateColumns(it, Manufacturers.FindByIdentification(Manufacturer)); if (it.CaptureObjects == null || it.CaptureObjects.Count == 0) { continue; } } catch { GXLogWriter.WriteLog(string.Format("Failed to read Profile Generic {0} columns.", it.LogicalName)); continue; } m_Objects.Add(it); } } finally { NotifyProgress(this, "", 0, 0); } }
/// <summary> /// Read DLMS Data from the device. /// </summary> /// <remarks> /// If access is denied return null. /// </remarks> /// <param name="data">Data to send.</param> /// <returns>Received data.</returns> public void ReadDLMSPacket(byte[] data, int tryCount, GXReplyData reply) { if (data == null) { return; } object eop = (byte)0x7E; //In network connection terminator is not used. if (client.InterfaceType == InterfaceType.WRAPPER && media is GXNet && !parent.UseRemoteSerial) { eop = null; } int pos = 0; bool succeeded = false; ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>() { AllData = false, Eop = eop, Count = 5, WaitTime = parent.WaitTime * 1000, }; lock (media.Synchronous) { if (data != null) { media.Send(data, null); } while (!succeeded && pos != 3) { succeeded = media.Receive(p); if (!succeeded) { //Try to read again... if (++pos != tryCount) { //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = 1; } System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); media.Send(data, null); continue; } string err = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(err, p.Reply); throw new Exception(err); } } try { //Loop until whole COSEM packet is received. while (!client.GetData(p.Reply, reply)) { //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = 1; } if (!media.Receive(p)) { //Try to read again... if (++pos != tryCount) { System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); continue; } string err = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(err, p.Reply); throw new Exception(err); } } } catch (Exception ex) { GXLogWriter.WriteLog("Received data:", p.Reply); throw ex; } } GXLogWriter.WriteLog(null, p.Reply); if (parent.OnTrace != null) { parent.OnTrace(parent, "-> " + DateTime.Now.ToLongTimeString(), p.Reply); } if (reply.Error != 0) { if (reply.Error == (int)ErrorCode.Rejected) { Thread.Sleep(1000); ReadDLMSPacket(data, tryCount, reply); } else { throw new GXDLMSException(reply.Error); } } }
void Media_OnTrace(object sender, TraceEventArgs e) { GXLogWriter.WriteLog(e.ToString()); }
public void InitializeConnection() { if (!string.IsNullOrEmpty(parent.Manufacturer)) { UpdateManufactureSettings(parent.Manufacturer); } if (media is GXSerial) { GXLogWriter.WriteLog("Initializing serial connection."); InitSerial(); connectionStartTime = DateTime.Now; } else if (media is GXNet) { GXLogWriter.WriteLog("Initializing Network connection."); InitNet(); //Some Electricity meters need some time before first message can be send. System.Threading.Thread.Sleep(500); } else if (media is Gurux.Terminal.GXTerminal) { GXLogWriter.WriteLog("Initializing Terminal connection."); InitTerminal(); } else { media.Open(); } try { GXReplyData reply = new GXReplyData(); byte[] data; client.Limits.WindowSizeRX = parent.WindowSizeRX; client.Limits.WindowSizeTX = parent.WindowSizeTX; client.Limits.MaxInfoRX = parent.MaxInfoRX; client.Limits.MaxInfoTX = parent.MaxInfoTX; client.MaxReceivePDUSize = parent.PduSize; client.Priority = parent.Priority; client.ServiceClass = parent.ServiceClass; data = SNRMRequest(); if (data != null) { ReadDataBlock(data, "Send SNRM request.", reply); GXLogWriter.WriteLog("Parsing UA reply succeeded."); //Has server accepted client. ParseUAResponse(reply.Data); } //Generate AARQ request. //Split requests to multiple packets if needed. //If password is used all data might not fit to one packet. reply.Clear(); ReadDataBlock(AARQRequest(), "Send AARQ request.", reply); try { //Parse reply. ParseAAREResponse(reply.Data); GXLogWriter.WriteLog("Parsing AARE reply succeeded."); } catch (Exception Ex) { reply.Clear(); ReadDLMSPacket(DisconnectRequest(), 1, reply); throw Ex; } //If authentication is required. if (client.Authentication > Authentication.Low) { foreach (byte[] it in client.GetApplicationAssociationRequest()) { GXLogWriter.WriteLog("Authenticating", it); reply.Clear(); ReadDLMSPacket(it, reply); } client.ParseApplicationAssociationResponse(reply.Data); } } catch (Exception ex) { if (media is GXSerial && parent.StartProtocol == StartProtocolType.IEC) { ReceiveParameters <string> p = new ReceiveParameters <string>() { Eop = (byte)0xA, WaitTime = parent.WaitTime * 1000 }; lock (media.Synchronous) { string data = (char)0x01 + "B0" + (char)0x03 + "\r\n"; media.Send(data, null); media.Receive(p); } } throw ex; } parent.KeepAliveStart(); }
/// <summary> /// After UpdateObjects call objects can be read using Objects property. /// </summary> public void UpdateObjects() { try { GXDLMSObjectCollection objs = Comm.GetObjects(); objs.Tag = this; int pos = 0; foreach (GXDLMSObject it in objs) { ++pos; NotifyProgress(this, "Creating object " + it.LogicalName, pos, objs.Count); m_Objects.Add(it); } GXLogWriter.WriteLog("--- Created " + m_Objects.Count.ToString() + " objects. ---"); //Read registers units and scalers. int cnt = Objects.Count; GXLogWriter.WriteLog("--- Reading scalers and units. ---"); for (pos = 0; pos != cnt; ++pos) { GXDLMSObject it = Objects[pos]; this.OnProgress(this, "Reading scalers and units.", cnt + pos + 1, 3 * cnt); if (it is GXDLMSRegister) { //Read scaler first. try { Comm.ReadValue(it, 3); } catch (Exception ex) { GXLogWriter.WriteLog(ex.Message); UpdateError(it, 3, ex); if (ex is GXDLMSException) { continue; } throw ex; } } if (it is GXDLMSDemandRegister) { try { //Read scaler first. Comm.ReadValue(it, 4); //Read Period Comm.ReadValue(it, 8); //Read number of periods Comm.ReadValue(it, 9); } catch (Exception ex) { GXLogWriter.WriteLog(ex.Message); UpdateError(it, 3, ex); if (ex is GXDLMSException) { continue; } throw ex; } } } GXLogWriter.WriteLog("--- Reading scalers and units end. ---"); if (!UseLogicalNameReferencing) { GXLogWriter.WriteLog("--- Reading Access rights. ---"); try { foreach (GXDLMSAssociationShortName sn in Objects.GetObjects(ObjectType.AssociationShortName)) { Comm.ReadValue(sn, 3); } } catch (Exception ex) { GXLogWriter.WriteLog(ex.Message); } GXLogWriter.WriteLog("--- Reading Access rights end. ---"); } this.OnProgress(this, "Reading profile generic columns.", cnt, cnt); foreach (Gurux.DLMS.Objects.GXDLMSProfileGeneric it in objs.GetObjects(ObjectType.ProfileGeneric)) { ++pos; //Read Profile Generic Columns. try { NotifyProgress(this, "Get profile generic columns", (2 * cnt) + pos, 3 * objs.Count); UpdateColumns(it, Manufacturers.FindByIdentification(Manufacturer)); if (it.CaptureObjects == null || it.CaptureObjects.Count == 0) { continue; } } catch { GXLogWriter.WriteLog(string.Format("Failed to read Profile Generic {0} columns.", it.LogicalName)); continue; } } } finally { NotifyProgress(this, "", 0, 0); } }
public byte[] Read(GXDLMSObject it, int attributeOrdinal) { byte[] tmp = client.Read(it, attributeOrdinal)[0]; GXLogWriter.WriteLog(string.Format("Reading object {0}, interface {1}", it.LogicalName, it.ObjectType), tmp); return(tmp); }