public void Write(GXDLMSObject obj, object target, int index, List<object> UpdatedObjects) { object value; GXReplyData reply = new GXReplyData(); for (int it = 1; it != (obj as IGXDLMSBase).GetAttributeCount() + 1; ++it) { reply.Clear(); if (obj.GetDirty(it, out value)) { //Read DLMS data type if not known. DataType type = obj.GetDataType(it); if (type == DataType.None) { byte[] data = client.Read(obj, it)[0]; ReadDataBlock(data, "Write object type " + obj.ObjectType, reply); type = reply.DataType; if (type == DataType.None) { throw new Exception("Failed to write value. Data type not set."); } obj.SetDataType(it, type); } try { foreach (byte[] tmp in client.Write(obj.Name, value, type, obj.ObjectType, it)) { ReadDataBlock(tmp, "Write object", reply); } obj.ClearDirty(it); //Read data once again to make sure it is updated. byte[] data = client.Read(obj, it)[0]; ReadDataBlock(data, "Read object " + obj.ObjectType, reply); value = reply.Value; if (value is byte[] && (type = obj.GetUIDataType(it)) != DataType.None) { value = GXDLMSClient.ChangeType((byte[])value, type); } client.UpdateValue(obj, it, value); } catch (GXDLMSException ex) { if (ex.ErrorCode == 3) { throw new Exception("Read/Write Failed."); } else { throw ex; } } } } }
/// <summary> /// Reset settings when connection is made or close. /// </summary> /// <param name="connected"></param> public void Reset(bool connected) { transaction = null; Settings.BlockIndex = 1; Settings.Count = Settings.Index = 0; Settings.Connected = false; replyData.Clear(); receivedData.Clear(); Settings.Password = null; if (!connected) { info.Clear(); Settings.ServerAddress = 0; Settings.ClientAddress = 0; } Settings.Authentication = Authentication.None; Settings.IsAuthenticationRequired = false; if (Settings.Cipher != null) { if (!connected) { Settings.Cipher.Reset(); } else { Settings.Cipher.Security = Gurux.DLMS.Enums.Security.None; } } }
/// <summary> /// Reset after connection is closed. /// </summary> public void Reset() { ConnectedClientAddress = 0; Reply.Clear(); Settings.ServerAddress = 0; Settings.ClientAddress = 0; Settings.Authentication = Authentication.None; if (Settings.Cipher != null) { Settings.Cipher.Reset(); } }
void ReadDataBlock(byte[][] data, string text, GXReplyData reply) { foreach (byte[] it in data) { reply.Clear(); ReadDataBlock(it, text, reply); } }
/// <summary> /// Read object. /// </summary> /// <param name="InitialValues"></param> /// <param name="obj"></param> /// <param name="attribute"></param> public void Read(object sender, GXDLMSObject obj, int attribute) { GXReplyData reply = new GXReplyData(); foreach (int it in (obj as IGXDLMSBase).GetAttributeIndexToRead()) { reply.Clear(); if (obj is GXDLMSProfileGeneric && it == 2) { if (OnBeforeRead != null) { OnBeforeRead(obj, it); } try { CurrentProfileGeneric = obj as GXDLMSProfileGeneric; OnDataReceived += new GXDLMSCommunicator.DataReceivedEventHandler(this.OnProfileGenericDataReceived); if (CurrentProfileGeneric.AccessSelector == AccessRange.Range || CurrentProfileGeneric.AccessSelector == AccessRange.Last) { byte[][] tmp = client.ReadRowsByRange(CurrentProfileGeneric, Convert.ToDateTime(CurrentProfileGeneric.From), Convert.ToDateTime(CurrentProfileGeneric.To)); ReadDataBlock(tmp[0], "Reading profile generic data", 1, reply); } else if (CurrentProfileGeneric.AccessSelector == AccessRange.Entry) { byte[][] tmp = client.ReadRowsByEntry(CurrentProfileGeneric, Convert.ToInt32(CurrentProfileGeneric.From), Convert.ToInt32(CurrentProfileGeneric.To)); ReadDataBlock(tmp[0], "Reading profile generic data " + CurrentProfileGeneric.Name, 1, reply); } else //Read all. { byte[] tmp = client.Read(CurrentProfileGeneric, 2)[0]; ReadDataBlock(tmp, "Reading profile generic data " + CurrentProfileGeneric.Name, 1, reply); } } finally { if (OnAfterRead != null) { OnAfterRead(obj, it); } OnDataReceived -= new GXDLMSCommunicator.DataReceivedEventHandler(OnProfileGenericDataReceived); } continue; } else { if (OnBeforeRead != null) { OnBeforeRead(obj, it); } byte[] data = client.Read(obj.Name, obj.ObjectType, it)[0]; try { ReadDataBlock(data, "Read object type " + obj.ObjectType + " index: " + it, reply); } catch (GXDLMSException ex) { if (ex.ErrorCode == 3 || //If read is denied. ex.ErrorCode == 4 || // Undefined object. ex.ErrorCode == 13) //Actaris returns access violation error. { obj.SetAccess(it, AccessMode.NoAccess); continue; } else { throw ex; } } if (obj is IGXDLMSBase) { object value = reply.Value; DataType type; if (value is byte[] && (type = obj.GetUIDataType(it)) != DataType.None) { value = GXDLMSClient.ChangeType((byte[])value, type); } client.UpdateValue(obj, it, value); } if (OnAfterRead != null) { OnAfterRead(obj, it); } obj.SetLastReadTime(it, DateTime.Now); //If only selected attribute is read. if (attribute != 0) { break; } } } }
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 { GXReplyData reply = new GXReplyData(); byte[] data; data = SNRMRequest(); if (data != null) { GXLogWriter.WriteLog("Send SNRM request.", data); ReadDLMSPacket(data, 1, reply); GXLogWriter.WriteLog("Parsing UA reply.\r\n" + reply.Data.ToString()); //Has server accepted client. ParseUAResponse(reply.Data); 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.Clear(); ReadDLMSPacket(it, reply); } GXLogWriter.WriteLog("Parsing AARE reply\r\n" + reply.Data.ToString()); try { //Parse reply. ParseAAREResponse(reply.Data); } catch (Exception Ex) { reply.Clear(); ReadDLMSPacket(DisconnectRequest(), 1, reply); throw Ex; } //If authentication is required. if (client.IsAuthenticationRequired) { 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; } GXLogWriter.WriteLog("Parsing AARE reply succeeded."); parent.KeepAliveStart(); }
public bool ReadDataBlock(byte[][] data, GXReplyData reply) { foreach (byte[] it in data) { reply.Clear(); ReadDataBlock(it, reply); } return true; }
public void UpdateImage(GXDLMSImageTransfer target, byte[] data, string Identification) { GXReplyData reply = new GXReplyData(); //Check that image transfer ia enabled. ReadDataBlock(Client.Read(target, 5), reply); Client.UpdateValue(target, 5, reply); if (!target.ImageTransferEnabled) { throw new Exception("Image transfer is not enabled"); } //Step 1: The client gets the ImageBlockSize. reply.Clear(); ReadDataBlock(Client.Read(target, 2), reply); Client.UpdateValue(target, 2, reply); // Step 2: The client initiates the Image transfer process. reply.Clear(); ReadDataBlock(target.ImageTransferInitiate(Client, Identification, data.Length), reply); // Step 3: The client transfers ImageBlocks. reply.Clear(); int ImageBlockCount; ReadDataBlock(target.ImageBlockTransfer(Client, data, out ImageBlockCount), reply); //Step 4: The client checks the completeness of the Image in //each server individually and transfers any ImageBlocks not (yet) transferred; reply.Clear(); Client.UpdateValue(target, 2, reply); // Step 5: The Image is verified; reply.Clear(); ReadDataBlock(target.ImageVerify(Client), reply); // Step 6: Before activation, the Image is checked; //Get list to imaages to activate. reply.Clear(); ReadDataBlock(Client.Read(target, 7), reply); Client.UpdateValue(target, 7, reply); bool bFound = false; foreach (GXDLMSImageActivateInfo it in target.ImageActivateInfo) { if (it.Identification == Identification) { bFound = true; break; } } //Read image transfer status. reply.Clear(); ReadDataBlock(Client.Read(target, 6), reply); Client.UpdateValue(target, 6, reply.Value); if (target.ImageTransferStatus != ImageTransferStatus.VerificationSuccessful) { throw new Exception("Image transfer status is " + target.ImageTransferStatus.ToString()); } if (!bFound) { throw new Exception("Image not found."); } //Step 7: Activate image. reply.Clear(); ReadDataBlock(target.ImageActivate(Client), reply); }
/// <summary> /// Read list of attributes. /// </summary> public void ReadList(List<KeyValuePair<GXDLMSObject, int>> list) { byte[][] data = Client.ReadList(list); GXReplyData reply = new GXReplyData(); List<object> values = new List<object>(); foreach (byte[] it in data) { ReadDataBlock(it, reply); if (reply.Value is object[]) { values.AddRange((object[])reply.Value); } else if (reply.Value != null) { //Value is null if data is send multiple frames. values.Add(reply.Value); } reply.Clear(); } if (values.Count != list.Count) { throw new Exception("Invalid reply. Read items count do not match."); } Client.UpdateValues(list, values); }
/// <summary> /// Read attribute value. /// </summary> public object Read(GXDLMSObject it, int attributeIndex) { GXReplyData reply = new GXReplyData(); if (!ReadDataBlock(Client.Read(it, attributeIndex), reply)) { reply.Clear(); Thread.Sleep(1000); if (!ReadDataBlock(Client.Read(it, attributeIndex), reply)) { if (reply.Error != 0) { throw new GXDLMSException(reply.Error); } } } //Update data type. if (it.GetDataType(attributeIndex) == DataType.None) { it.SetDataType(attributeIndex, reply.DataType); } return Client.UpdateValue(it, attributeIndex, reply.Value); }
public void InitializeConnection(GXManufacturer man) { Manufacturer = man; UpdateManufactureSettings(man.Identification); if (Media is GXSerial) { Console.WriteLine("Initializing serial connection."); InitSerial(); } else if (Media is GXNet) { Console.WriteLine("Initializing Network connection."); InitNet(); //Some Electricity meters need some time before first message can be send. System.Threading.Thread.Sleep(500); } else { throw new Exception("Unknown media type."); } GXReplyData reply = new GXReplyData(); byte[] data; data = Client.SNRMRequest(); if (data != null) { if (Trace) { Console.WriteLine("Send SNRM request." + GXCommon.ToHex(data, true)); } ReadDLMSPacket(data, reply); if (Trace) { Console.WriteLine("Parsing UA reply." + reply.ToString()); } //Has server accepted client. Client.ParseUAResponse(reply.Data); Console.WriteLine("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 Client.AARQRequest()) { if (Trace) { Console.WriteLine("Send AARQ request", GXCommon.ToHex(it, true)); } reply.Clear(); ReadDLMSPacket(it, reply); } if (Trace) { Console.WriteLine("Parsing AARE reply" + reply.ToString()); } //Parse reply. Client.ParseAAREResponse(reply.Data); reply.Clear(); //Get challenge Is HSL authentication is used. if (Client.IsAuthenticationRequired) { foreach (byte[] it in Client.GetApplicationAssociationRequest()) { reply.Clear(); ReadDLMSPacket(it, reply); } Client.ParseApplicationAssociationResponse(reply.Data); } Console.WriteLine("Parsing AARE reply succeeded."); }