Exemple #1
0
 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);
 }
Exemple #7
0
        /// <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);
        }
Exemple #11
0
 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);
 }
Exemple #20
0
        /// <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();
        }
Exemple #24
0
 /// <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);
     }
 }
Exemple #25
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);
 }