예제 #1
0
 /// <summary>
 /// Constructor.
 /// </summary>
 public GXCommunicatation(Gurux.DLMS.GXDLMSClient dlms, IGXMedia media, bool initializeIEC, Authentication authentication, string password)
 {
     Client                = dlms;
     Media                 = media;
     InitializeIEC         = initializeIEC;
     Client.Authentication = authentication;
     Client.Password       = ASCIIEncoding.ASCII.GetBytes(password);
     //Delete trace file if exists.
     if (File.Exists("trace.txt"))
     {
         File.Delete("trace.txt");
     }
 }
 /// <summary>
 /// Constructor.
 /// </summary>
 public GXCommunicatation(Gurux.DLMS.GXDLMSClient dlms, IGXMedia media, bool initializeIEC, Gurux.DLMS.Authentication authentication, string password)
 {
     Client = dlms;
     Media = media;
     InitializeIEC = initializeIEC;
     Client.Authentication = authentication;
     Client.Password = ASCIIEncoding.ASCII.GetBytes(password);
     //Delete trace file if exists.
     if (File.Exists("trace.txt"))
     {
         File.Delete("trace.txt");
     }
 }
예제 #3
0
 public void Close()
 {
     if (Media != null && Client != null)
     {
         try
         {
             //Console.WriteLine("Disconnecting from the meter.");
             ReadDLMSPacket(Client.DisconnectRequest());
             Media.Close();
         }
         catch
         {
         }
         Media  = null;
         Client = null;
     }
 }
        public void Close()
        {
            if (Media != null && Client != null)
            {
                try
                {
                    //Console.WriteLine("Disconnecting from the meter.");
                    ReadDLMSPacket(Client.DisconnectRequest());
                    Media.Close();
                }
                catch
                {

                }
                Media = null;
                Client = null;
            }
        }
예제 #5
0
 void AddColumn(GXDLMSClient cosem, GXManufacturer man, GXDLMSTable table, byte[] ln, object scalar, int index, string name)
 {
     string logicanName = null;            
     if (ln != null)
     {
         logicanName = GXHelpers.ConvertFromDLMS(ln, DataType.OctetString, DataType.OctetString, false).ToString();
         if (string.IsNullOrEmpty(name))
         {
             GXObisCode code = man.ObisCodes.FindByLN(ObjectType.None, logicanName, null);
             if (code != null)
             {
                 name = code.Description;
             }
             else
             {
                 name = logicanName;
             }
         }
     }
     if (scalar == null)
     {
         GXDLMSProperty prop = new GXDLMSProperty(ObjectType.Data, logicanName, 0, name, index, DataType.DateTime);
         prop.ValueType = DataType.DateTime;
         prop.AccessMode = Gurux.Device.AccessMode.Read;
         table.Columns.Add(prop);
     }
     else
     {
         object[] tmp = (object[])scalar;
         Gurux.DLMS.AddIn.GXDLMSRegister prop = new Gurux.DLMS.AddIn.GXDLMSRegister();
         prop.Scaler = Math.Pow(10, Convert.ToInt32(tmp[0]));
         prop.Unit = tmp[1].ToString();
         prop.LogicalName = logicanName;
         prop.Name = name;
         prop.AttributeOrdinal = index;
         prop.DLMSType = DataType.UInt32;
         prop.ValueType = DataType.Float64;
         prop.AccessMode = Gurux.Device.AccessMode.Read;
         table.Columns.Add(prop);
     }
 }
예제 #6
0
 public byte[][] ImageVerify(GXDLMSClient client)
 {
     return client.Method(this, 3, 0, DataType.Int8);
 }
예제 #7
0
 public byte[][] ImageTransferInitiate(GXDLMSClient client, string imageIdentifier, long imageSize)
 {
     if (ImageBlockSize == 0)
     {
         throw new Exception("Invalid image block size");
     }
     List<byte> data = new List<byte>();
     data.Add((byte)DataType.Structure);
     data.Add((byte)2);
     GXCommon.SetData(data, DataType.OctetString, ASCIIEncoding.ASCII.GetBytes(imageIdentifier));
     GXCommon.SetData(data, DataType.UInt32, imageSize);
     return client.Method(this, 1, data.ToArray(), DataType.Array);
 }
예제 #8
0
 /// <summary>
 /// Removes X.509 v3 certificate from the server using entity.
 /// </summary>
 /// <param name="client">DLMS client that is used to generate action.</param>
 /// <param name="entity">Certificate entity type.</param>
 /// <param name="type">Certificate type.</param>
 /// <param name="systemTitle">System title.</param>
 /// <returns>Generated action.</returns>
 public byte[][] RemoveCertificateByEntity(GXDLMSClient client, CertificateEntity entity, CertificateType type, byte[] systemTitle)
 {
     GXByteBuffer bb = new GXByteBuffer();
     bb.SetUInt8(DataType.Structure);
     bb.SetUInt8(2);
     //Add enum
     bb.SetUInt8(DataType.Enum);
     bb.SetUInt8(0);
     //Add certificate_identification_by_entity
     bb.SetUInt8(DataType.Structure);
     bb.SetUInt8(3);
     //Add certificate_entity
     bb.SetUInt8(DataType.Enum);
     bb.SetUInt8(entity);
     //Add certificate_type
     bb.SetUInt8(DataType.Enum);
     bb.SetUInt8(type);
     //system_title
     GXCommon.SetData(client.Settings, bb, DataType.OctetString, systemTitle);
     return client.Method(this, 8, bb.Array(), DataType.OctetString);
 }
예제 #9
0
 /// <summary>
 ///  Imports an X.509 v3 certificate of a public key.
 /// </summary>
 /// <param name="client">DLMS client that is used to generate action.</param>
 /// <param name="key">Public key.</param>
 /// <returns>Generated action.</returns>
 public byte[][] Import(GXDLMSClient client, CngKey key)
 {
     return ImportCertificate(client, key.Export(CngKeyBlobFormat.EccPublicBlob));
 }
예제 #10
0
 /// <summary>
 /// Agree on one or more symmetric keys using the key agreement algorithm.
 /// </summary>
 /// <param name="client"> DLMS client that is used to generate action.</param>
 /// <param name="list"> List of keys.</param>
 /// <returns>Generated action.</returns>
 public byte[][] keyAgreement(GXDLMSClient client, List<KeyValuePair<GlobalKeyType, byte[]>> list)
 {
     if (list == null || list.Count == 0)
     {
         throw new ArgumentException("Invalid list. It is empty.");
     }
     GXByteBuffer bb = new GXByteBuffer();
     bb.SetUInt8(DataType.Array);
     bb.SetUInt8((byte)list.Count);
     foreach (KeyValuePair<GlobalKeyType, byte[]> it in list)
     {
         bb.SetUInt8(DataType.Structure);
         bb.SetUInt8(2);
         GXCommon.SetData(client.Settings, bb, DataType.Enum, it.Key);
         GXCommon.SetData(client.Settings, bb, DataType.OctetString, it.Value);
     }
     return client.Method(this, 3, bb.Array(), DataType.Array);
 }
예제 #11
0
 /// <summary>
 /// Shifts the time by n (-900 <= n <= 900) s.
 /// </summary>
 /// <param name="time"></param>
 /// <returns></returns>
 public byte[][] ShiftTime(GXDLMSClient client, int time)
 {
     if (time < -900 || time > 900)
     {
         throw new ArgumentOutOfRangeException("Invalid shift time.");
     }
     return client.Method(this, 6, time, DataType.Int16);            
 }
예제 #12
0
 internal void CreateColumns(Gurux.Common.IGXMedia media, GXDLMSDevice Device, GXManufacturer man, int wt, GXDLMSClient cosem, IGXManufacturerExtension Extension, GXCategory dataItems, GXCategory registers, GXDLMSObject it, GXDLMSTable table)
 {            
 }
예제 #13
0
		/// <summary>
		/// Import properties from the device.
		/// </summary>
        /// <param name="addinPages">Addin pages.</param>
        /// <param name="device">The target GXDevice to put imported items.</param>
		/// <param name="media">A media connection to the device.</param>
		/// <returns>True if there were no errors, otherwise false.</returns>
        public override void ImportFromDevice(Control[] addinPages, GXDevice device, IGXMedia media)
		{
            media.Open();
			GXDLMSDevice Device = (GXDLMSDevice)device;            
			int wt = Device.WaitTime;
			GXDLMSClient cosem = null;
            byte[] data, reply = null;            
            IGXManufacturerExtension Extension = null;
			try
			{                
				//Initialize connection.
                cosem = new GXDLMSClient();
                cosem.UseLogicalNameReferencing = Device.UseLogicalNameReferencing;				
                if (Device.Manufacturers == null)
                {
                    Device.Manufacturers = new GXManufacturerCollection();
                    GXManufacturerCollection.ReadManufacturerSettings(Device.Manufacturers);
                }
                GXManufacturer man = Device.Manufacturers.FindByIdentification(Device.Identification);
                if (!string.IsNullOrEmpty(man.Extension))
                {
                    Type t = Type.GetType(man.Extension);
                    Extension = Activator.CreateInstance(t) as IGXManufacturerExtension;
                }

                if (!Device.UseRemoteSerial && media is GXNet) //If media is network.
				{
                    if (Device.SupportNetworkSpecificSettings)
                    {
                        cosem.InterfaceType = Gurux.DLMS.InterfaceType.Net;
                    }
				}
				else if (media is GXSerial) //If media is serial.
				{
                    byte terminator = 0xA;
                    if (Device.StartProtocol == StartProtocolType.IEC)
                    {
                        GXSerial serial = media as GXSerial;
                        serial.Eop = terminator;
                        serial.Eop = terminator;
                        //Init IEC connection. This must done first with serial connections.
                        string str = "/?" + Device.SerialNumber + "!\r\n";
                        ReceiveParameters<string> args = new ReceiveParameters<string>()
                        {
                            Eop = terminator,
                            WaitTime = wt
                        };
                        lock (media.Synchronous)
                        {
                            media.Send(str, null);
                            do
                            {
                                args.Reply = null;                                
                                if (!media.Receive(args))
                                {
                                    throw new Exception("Failed to receive reply from the device in given time.");
                                }
                            }
                            while (str == args.Reply);//Remove echo
                        }
                        string answer = args.Reply.ToString();                        
                        if (answer[0] != '/')
                        {
                            throw new Exception("Invalid responce.");
                        }
                        string manufactureID = answer.Substring(1, 3);
                        char baudrate = answer[4];
                        if (baudrate == ' ')
                        {
                            baudrate = '5';
                        }
                        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.");
                        }                        
                        //Send ACK
                        //Send Protocol control character
                        byte controlCharacter = (byte)'2';// "2" HDLC protocol procedure (Mode E)
                        //Send Baudrate character
                        //Mode control character 
                        byte ModeControlCharacter = (byte)'2';//"2" //(HDLC protocol procedure) (Binary mode)
                        //We are not receive anything.
                        data = new byte[] { 0x06, controlCharacter, (byte)baudrate, ModeControlCharacter, 0x0D, 0x0A };                        
                        lock (media.Synchronous)
                        {
                            args.Reply = null;                            
                            media.Send(data, null);                                                       
                            //This is in standard. Do not remove sleep.
                            //Some meters work without it, but some do not.
                            System.Threading.Thread.Sleep(500);
                            serial.BaudRate = baudRate;
                            ReceiveParameters<byte[]> args2 = new ReceiveParameters<byte[]>()
                            {
                                Eop = terminator,
                                WaitTime = 100
                            };
                            //If this fails, just read all data.
                            if (!media.Receive(args2))
                            {
                                //Read buffer.
                                args2.AllData = true;
                                args2.WaitTime = 1;
                                media.Receive(args2);
                            }
                            serial.DataBits = 8;
                            serial.Parity = Parity.None;
                            serial.StopBits = StopBits.One;
                            serial.DiscardInBuffer();
                            serial.DiscardOutBuffer();
                            serial.ResetSynchronousBuffer();
                        }                        
                    }
				}
                media.Eop = (byte) 0x7E;
                cosem.Authentication = (Gurux.DLMS.Authentication)Device.Authentication;
                object clientAdd = null;
                if (cosem.Authentication == Authentication.None)
                {
                    clientAdd = Device.ClientID;
                }
                else if (cosem.Authentication == Authentication.Low)
                {
                    clientAdd = Device.ClientIDLow;
                }
                else if (cosem.Authentication == Authentication.High)
                {
                    clientAdd = Device.ClientIDHigh;
                }
                if (!string.IsNullOrEmpty(Device.Password))
                {
                    cosem.Password = ASCIIEncoding.ASCII.GetBytes(Device.Password);
                }
                else
                {
                    cosem.Password = null;
                }
                //If network media is used check is manufacturer supporting IEC 62056-47
                if (!Device.UseRemoteSerial && media is GXNet && Device.SupportNetworkSpecificSettings)
                {
                    cosem.InterfaceType = InterfaceType.Net;
                    media.Eop = null;
                    cosem.ClientID = Convert.ToUInt16(clientAdd);
                    cosem.ServerID = Convert.ToUInt16(Device.PhysicalAddress);
                }
                else
                {
                    if (Device.HDLCAddressing == HDLCAddressType.Custom)
                    {
                        cosem.ClientID = clientAdd;
                    }
                    else
                    {
                        cosem.ClientID = (byte)(Convert.ToByte(clientAdd) << 1 | 0x1);
                    }
                    if (Device.HDLCAddressing == HDLCAddressType.SerialNumber)
                    {
                        cosem.ServerID = GXManufacturer.CountServerAddress(Device.HDLCAddressing, Device.SNFormula, Convert.ToUInt32(Device.SerialNumber), Device.LogicalAddress);
                    }
                    else
                    {
                        cosem.ServerID = GXManufacturer.CountServerAddress(Device.HDLCAddressing, Device.SNFormula, Device.PhysicalAddress, Device.LogicalAddress);
                    }                    
                }
                byte[] allData = null;
                data = cosem.SNRMRequest();
				//General Network connection don't need SNRMRequest.
				if (data != null)
				{
					Trace("--- Initialize DLMS connection\r\n");
					try
					{
						reply = ReadDLMSPacket(cosem, media, data, wt);
					}
					catch (Exception Ex)
					{
						throw new Exception("DLMS Initialize failed. " + Ex.Message);
					}
					//Has server accepted client.
					cosem.ParseUAResponse(reply);
				}
				Trace("Connecting\r\n");
                media.ResetSynchronousBuffer();
				try
				{                    
                    foreach (byte[] it in cosem.AARQRequest(null))
                    {                        
                        reply = ReadDLMSPacket(cosem, media, it, wt);
                    }
				}
				catch (Exception Ex)
				{
					throw new Exception("DLMS AARQRequest failed. " + Ex.Message);
				}
                cosem.ParseAAREResponse(reply);
                //Now 1/5 or actions is done.
                Progress(1, 5);
                Trace("Read Objects\r\n");
                try
				{
                    allData = ReadDataBlock(cosem, media, cosem.GetObjectsRequest(), wt, 1);
				}
				catch (Exception Ex)
				{
					throw new Exception("DLMS AARQRequest failed. " + Ex.Message);
				}
                Trace("--- Parse Objects ---\r\n");
                GXDLMSObjectCollection objs = cosem.ParseObjects((byte[])allData, true);

			    allData = null;
				//Now we know exact number of read registers. Update progress bar again.
                int max = objs.Count;				                
				Trace("--- Read scalars ---\r\n");
				//Now 2/5 or actions is done.
                Progress(2 * max, 5 * max);
                GXCategory dataItems = new GXCategory();
                dataItems.Name = "Data Items";
                GXCategory registers = new GXCategory();
                registers.Name = "Registers";
                Device.Categories.Add(dataItems);
                Device.Categories.Add(registers);
                int pos = 0;
                foreach (GXDLMSObject it in objs)
                {
                    ++pos;
                    //Skip association views.
                    if (it.ObjectType == ObjectType.AssociationLogicalName ||
                        it.ObjectType == ObjectType.AssociationShortName)
                    {
                        continue;
                    }
                    if (it.ObjectType != ObjectType.ProfileGeneric)
                    {
                        object prop = UpdateData(media, Device, wt, cosem, man, it, dataItems, registers);
                        //Read scaler and unit
                        if (it.ObjectType == ObjectType.Register)
                        {
                            try
                            {
                                data = cosem.Read(it.Name, it.ObjectType, 3)[0];
                                allData = ReadDataBlock(cosem, media, data, wt, 2);
                                cosem.UpdateValue(allData, it, 3);
                                Gurux.DLMS.Objects.GXDLMSRegister item = it as Gurux.DLMS.Objects.GXDLMSRegister;
                                GXDLMSRegister r = prop as GXDLMSRegister;
                                r.Scaler = item.Scaler;
                                r.Unit = item.Unit.ToString();
                            }
                            //Ignore HW error and read next.
                            catch (GXDLMSException)
                            {
                                continue;
                            }
                            catch (Exception Ex)
                            {
                                throw new Exception("DLMS Register Scaler and Unit read failed. " + Ex.Message);
                            }
                        }
                        //Read scaler and unit
                        else if (it.ObjectType == ObjectType.ExtendedRegister)
                        {
                            try
                            {
                                data = cosem.Read(it.Name, it.ObjectType, 3)[0];
                                allData = ReadDataBlock(cosem, media, data, wt, 2);
                                cosem.UpdateValue(allData, it, 3);
                                Gurux.DLMS.Objects.GXDLMSExtendedRegister item = it as Gurux.DLMS.Objects.GXDLMSExtendedRegister;
                                GXDLMSCategory cat = prop as GXDLMSCategory;
                                GXDLMSRegister r = cat.Properties[0] as GXDLMSRegister;
                                r.Scaler = item.Scaler;
                                r.Unit = item.Unit.ToString();
                                cat.Properties[1].SetValue(item.Scaler.ToString() + ", " + item.Unit.ToString(), true, PropertyStates.None);
                            }
                            //Ignore HW error and read next.
                            catch (GXDLMSException)
                            {
                                continue;
                            }
                            catch (Exception Ex)
                            {
                                throw new Exception("DLMS Register Scaler and Unit read failed. " + Ex.Message);
                            }
                        }
                        //Read scaler and unit
                        else if (it.ObjectType == ObjectType.DemandRegister)
                        {
                            try
                            {
                                data = cosem.Read(it.Name, it.ObjectType, 3)[0];
                                allData = ReadDataBlock(cosem, media, data, wt, 2);
                                cosem.UpdateValue(allData, it, 3);
                                Gurux.DLMS.Objects.GXDLMSDemandRegister item = it as Gurux.DLMS.Objects.GXDLMSDemandRegister;
                                GXDLMSCategory cat = prop as GXDLMSCategory;
                                cat.Properties[2].SetValue(item.Scaler.ToString() + ", " + item.Unit.ToString(), true, PropertyStates.None);

                                GXDLMSRegister r = cat.Properties[0] as GXDLMSRegister;
                                r.Scaler = item.Scaler;
                                r.Unit = item.Unit.ToString();
                                r = cat.Properties[1] as GXDLMSRegister;
                                r.Scaler = item.Scaler;
                                r.Unit = item.Unit.ToString();
                            }
                            //Ignore HW error and read next.
                            catch (GXDLMSException)
                            {
                                continue;
                            }
                            catch (Exception Ex)
                            {
                                throw new Exception("DLMS Register Scaler and Unit read failed. " + Ex.Message);
                            }
                        }                        
                    }
                    //Now 3/5 actions is done.
                    double tmp = pos * max; 
                    tmp /= max;
                    tmp += 2 * max;
                    Progress((int) tmp , 5 * max);
                }
                //Now 3/5 actions is done.
                Progress(3 * max, 5 * max);
                Trace("--- Read Generic profiles ---\r\n");
                GXDLMSObjectCollection pg = objs.GetObjects(ObjectType.ProfileGeneric);
                foreach (GXDLMSProfileGeneric it in pg)
                {
                    try
                    {
                        allData = ReadDataBlock(cosem, media, cosem.Read(it.Name, it.ObjectType, 3)[0], wt, 3);
                        cosem.UpdateValue(allData, it, 3);
                        UpdateData(media, Device, wt, cosem, man, it, dataItems, registers);
                    }
                    //Ignore HW error and read next.
                    catch (GXDLMSException)
                    {
                        continue;
                    }
                    catch (Exception Ex)
                    {
                        Trace("DLMS Generic Profile read failed. " + Ex.Message + Environment.NewLine);
                    }
                }
                //Now 4/5 actions is done.
                Progress(4 * max, 5 * max);            

                //Update IEC HDLC interval if found. 
                GXDLMSObjectCollection objects = objs.GetObjects(ObjectType.IecHdlcSetup);
                if (objects.Count != 0)
                {
                    allData = ReadDataBlock(cosem, media, cosem.Read(objects[0].Name, objects[0].ObjectType, 8)[0], wt, 5);
                    //Minus 10 second.
                    Device.Keepalive.Interval = (Convert.ToInt32(cosem.GetValue(allData)) - 10) * 1000;
                }

                //Now all actions are done.
                Progress(max, max);
                Trace("--- Succeeded ---\r\n");
			}
			finally
			{                
                if (cosem != null && media != null)
				{
					Trace("--- Disconnecting ---\r\n");
                    byte[] allData = null;
					if (cosem != null)
					{
						//Network standard don't need this.					
                        if (!(media is GXNet && Device.SupportNetworkSpecificSettings))
						{
							try
							{
								reply = ReadDLMSPacket(cosem, media, cosem.DisconnectRequest(), wt);
								cosem.GetDataFromPacket(reply, ref allData);
							}
							catch (Exception Ex)
							{
								Trace("DisconnectRequest failed. " + Ex.Message);
							}
						}
					}
					if (media != null)
					{
						media.Close();
						media = null;
					}
					Trace("--- Disconnected ---\r\n--- Done---\r\n");					
				}
			}			
		}
예제 #14
0
        internal byte[] ReadDLMSPacket(GXDLMSClient cosem, Gurux.Common.IGXMedia media, byte[] data, int wt)
		{
			if (data == null)
			{
				return null;
			}
            ReceiveParameters<byte[]> args = new ReceiveParameters<byte[]>()
            {
                Eop = (byte)0x7E,
                Count = 5,
                WaitTime = wt
            };
            if (cosem.InterfaceType == InterfaceType.Net)
            {
                args.Eop = null;
                args.Count = 8;
                args.AllData = true;
            }
            int pos = 0;
            bool succeeded = false;
            lock (media.Synchronous)
            {
                media.Send(data, null);
                while (!succeeded && pos != 3)
                {
                    succeeded = media.Receive(args);
                    if (!succeeded)
                    {
                        //Try to read again...
                        if (++pos != 3)
                        {
                            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, (byte[])args.Reply);
                        throw new Exception(err);
                    }
                }                
                //Loop until whole m_Cosem packet is received.                
                while (!(succeeded = cosem.IsDLMSPacketComplete(args.Reply)))
                {
                    if (!media.Receive(args))
                    {
                        //Try to read again...
                        if (++pos != 3)
                        {
                            System.Diagnostics.Debug.WriteLine("Data receive failed. Try to resend " + pos.ToString() + "/3");
                            continue;
                        }
                        string err = "Failed to receive reply from the device in given time.";
                        GXLogWriter.WriteLog(err, (byte[])args.Reply);
                        throw new Exception(err);
                    }
                }                
            }
            object[,] errors = cosem.CheckReplyErrors(data, args.Reply);
            if (errors != null)
            {
                int error = (int)errors[0, 0];
                throw new GXDLMSException(error);
            }
            return args.Reply;
		}
 public GXDLMSCommunicator(GXDLMSDevice parent, Gurux.Common.IGXMedia media)
 {
     Parent  = parent;
     Media   = media;
     m_Cosem = new Gurux.DLMS.GXDLMSClient();
 }
예제 #16
0
 public void UpdateColumns(GXDLMSDevice Device, 
             GXManufacturer man, GXDLMSClient cosem,
             Gurux.Common.IGXMedia media, int wt, Gurux.DLMS.Objects.GXDLMSObject it,
             GXDLMSTable table, GXDLMSAddIn parent, GXCategory dataItems, GXCategory registers)
 {
     //Reading data.                
     //If Load profile1
     if (it.LogicalName == "0.0.99.1.2.255")
     {
         //Read Load Profile 1 information
         byte[] allData = parent.ReadDataBlock(cosem, media, cosem.Read("0.0.99.128.1.255", ObjectType.ProfileGeneric, 2)[0], wt, 0);
         object[] items = (object[])((object[])cosem.GetValue(allData)).GetValue(0);
         int pos = 0;
         AddColumn(cosem, man, table, null, null, 0, "DateTime");
         AddColumn(cosem, man, table, null, null, 1, "Status");
         AddColumn(cosem, man, table, (byte[])items.GetValue(pos), items.GetValue(pos + 1), 2, null);
         pos += 2;
         AddColumn(cosem, man, table, (byte[])items.GetValue(pos), items.GetValue(pos + 1), 3, null);
         pos += 2;
         AddColumn(cosem, man, table, (byte[])items.GetValue(pos), items.GetValue(pos + 1), 4, null);
         pos += 2;
         AddColumn(cosem, man, table, (byte[])items.GetValue(pos), items.GetValue(pos + 1), 5, null);
         pos += 2;
         AddColumn(cosem, man, table, (byte[])items.GetValue(pos), items.GetValue(pos + 1), 6, null);
         pos += 2;
         AddColumn(cosem, man, table, (byte[])items.GetValue(pos), items.GetValue(pos + 1), 7, null);
         pos += 2;
         AddColumn(cosem, man, table, (byte[])items.GetValue(pos), items.GetValue(pos + 1), 8, null);
         pos += 2;
         AddColumn(cosem, man, table, (byte[])items.GetValue(pos), items.GetValue(pos + 1), 9, null);                
         return;
     }           
     parent.CreateColumns(media, Device, man, wt, cosem, this, dataItems, registers, it, table);                    
 }
예제 #17
0
 /// <summary>
 /// Update categories data.
 /// </summary>
 /// <param name="trace"></param>
 /// <param name="progressbar"></param>
 /// <param name="media"></param>
 /// <param name="Device"></param>
 /// <param name="wt"></param>
 /// <param name="cosem"></param>
 /// <param name="man"></param>
 /// <param name="objs"></param>
 /// <param name="dataItems"></param>
 /// <param name="registers"></param>
 private object UpdateData(Gurux.Common.IGXMedia media, GXDLMSDevice Device, int wt, GXDLMSClient cosem, GXManufacturer man, GXDLMSObject it, GXCategory dataItems, GXCategory registers)
 {
     GXObisCode code = man.ObisCodes.FindByLN(it.ObjectType, it.LogicalName, null);            
     if (it.ObjectType == ObjectType.Register)
     {
         GXDLMSRegister prop = new GXDLMSRegister();
         UpdateObject(it, prop, 2);
         registers.Properties.Add(prop);
         return prop;
     }
     else if (it.ObjectType == Gurux.DLMS.ObjectType.Data)
     {
         GXDLMSProperty prop = new GXDLMSProperty();
         prop.ObjectType = ObjectType.Data;
         UpdateObject(it, prop, 2);
         dataItems.Properties.Add(prop);
         return prop;
     }
     else if (it.ObjectType == Gurux.DLMS.ObjectType.ProfileGeneric)
     {
         GXDLMSProfileGeneric pg = it as GXDLMSProfileGeneric;
         GXDLMSTable table = new GXDLMSTable();
         table.Name = it.LogicalName + " " + it.Description;
         table.ShortName = it.ShortName;
         table.LogicalName = it.LogicalName;
         table.AccessMode = Gurux.Device.AccessMode.Read;
         foreach(var it2 in pg.CaptureObjects)
         {
             GXDLMSProperty prop;
             if (it2.Key is Gurux.DLMS.Objects.GXDLMSRegister)
             {
                 Gurux.DLMS.Objects.GXDLMSRegister tmp = it2.Key as Gurux.DLMS.Objects.GXDLMSRegister;
                 GXDLMSRegister r = new GXDLMSRegister();
                 prop = r;
                 r.Scaler = tmp.Scaler;
                 r.Unit = tmp.Unit.ToString();                    
             }
             else
             {
                 prop = new GXDLMSProperty();
             }
             int index = it2.Value.AttributeIndex;
             prop.Name = it2.Key.LogicalName + " " + it2.Key.Description;
             prop.ObjectType = it2.Key.ObjectType;
             prop.AttributeOrdinal = index;
             prop.LogicalName = it2.Key.LogicalName;
             table.Columns.Add(prop);
             prop.DLMSType = it.GetDataType(index);                    
             prop.ValueType = it2.Key.GetUIDataType(index);
         }
         Device.Tables.Add(table);
         return table; 
     }
     GXDLMSCategory cat = new GXDLMSCategory();
     cat.ObjectType = it.ObjectType;
     UpdateObject(it, cat);
     Device.Categories.Add(cat);
     return cat;            
 }
예제 #18
0
 /// <summary>
 /// Activates and strengthens the security policy.
 /// </summary>
 /// <param name="client">DLMS client that is used to generate action.</param>
 /// <param name="security">New security level.</param>
 /// <returns>Generated action.</returns>
 public byte[][] Activate(GXDLMSClient client, Gurux.DLMS.Enums.Security security)
 {
     return client.Method(this, 1, GetSecurityValue(security), DataType.Enum);
 }
        private static void MainProcessing(object state)
        {
            IGXMedia media = null;
            GXCommunicatation comm = null;
            Gurux.Net.GXNet net = null;

            if ((!Environment.UserInteractive) && (args.Length == 0))	// when in service mode, get arguments from commandline if failed from onStart method
                args = Environment.CommandLine.Split(new char[] { ' ' });

            if (!Environment.UserInteractive && !running)
                return;

            try
            {
                logFile = new StreamWriter(File.Open(logFileName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite));
                logFile.WriteLine("\n");

                //Handle command line parameters.
                String id = "lgz", host = "", port = "4095", pw = "";
                String lt = "-1";
                bool trace = false, iec = true;
                int loopTime = -1;
                Authentication auth = Authentication.None;
                foreach (string it in args)
                {
                    String item = it.Trim().ToLower();
                    if (string.Compare(item, "/u", true) == 0)//Update
                    {
                        //Get latest manufacturer settings from Gurux web server.
                        GXManufacturerCollection.UpdateManufactureSettings();
                    }
                    else if (item.StartsWith("/m="))//Manufacturer
                    {
                        id = item.Replace("/m=", "");
                    }
                    else if (item.StartsWith("/host=")) //Host
                    {
                        host = item.Replace("/host=", "");
                    }
                    else if (item.StartsWith("/p="))// TCP/IP Port
                    {
                        media = new Gurux.Net.GXNet();
                        port = item.Replace("/p=", "");
                    }
                    else if (item.StartsWith("/sp="))//Serial Port
                    {
                        port = item.Replace("/sp=", "");
                        media = new GXSerial();
                    }
                    else if (item.StartsWith("/t"))//Are messages traced.
                    {
                        trace = true;
                    }
                    else if (item.StartsWith("/s="))//Start
                    {
                        String tmp = item.Replace("/s=", "");
                        iec = string.Compare(tmp, "dlms", true) != 0;
                    }
                    else if (item.StartsWith("/a="))//Authentication
                    {
                        auth = (Authentication)Enum.Parse(typeof(Authentication), it.Trim().Replace("/a=", ""));
                    }
                    else if (item.StartsWith("/pw="))//Password
                    {
                        pw = it.Trim().Replace("/pw=", "");
                    }
                    else if (item.StartsWith("/l="))// loop time
                    {
                        lt = item.Replace("/l=", "");
                    }
                    else if (item.StartsWith("/h"))// help
                    {
                        ShowHelp();
                        return;
                    }
                    else if (item.StartsWith("/sm=")) //sitemap
                    {
                        sitesMapPath = it.Trim().Replace("/sm=", "");
                    }
                    else if (item.StartsWith("/is=")) //IAM server
                    {
                        IAMServer = it.Trim().Replace("/is=", "");
                    }
                }
                if (media == null)
                    media = new Gurux.Net.GXNet();

                int.TryParse(lt, out loopTime);

                Version version = Assembly.GetExecutingAssembly().GetName().Version;

                if (!Environment.UserInteractive)
                    TraceLine(logFile, string.Format("IAM Reader OPEN SOURCE EXAMPLE Service ver. {0} started with loop time={1} min.", version.ToString(3), loopTime));
                else
                    TraceLine(logFile, string.Format("IAM Reader OPEN SOURCE EXAMPLE ver. {0} started with loop time={1} min.", version.ToString(3), loopTime));

                logFile.Flush();

                //Initialize connection settings.
                if (media is GXSerial)
                {
                    GXSerial serial = media as GXSerial;
                    serial.PortName = port;
                    if (iec)
                    {
                        serial.BaudRate = 300;
                        serial.DataBits = 7;
                        serial.Parity = System.IO.Ports.Parity.Even;
                        serial.StopBits = System.IO.Ports.StopBits.One;
                    }
                    else
                    {
                        serial.BaudRate = 9600;
                        serial.DataBits = 8;
                        serial.Parity = System.IO.Ports.Parity.None;
                        serial.StopBits = System.IO.Ports.StopBits.One;
                    }
                }
                else if (media is GXNet)
                {
                    /*Gurux.Net.GXNet*/
                    net = media as GXNet;
                    net.Port = Convert.ToInt32(port);
                    net.HostName = host;
                    net.Protocol = Gurux.Net.NetworkType.Tcp;
                }
                else
                {
                    throw new Exception("Unknown media type.");
                }

                //Update manufacturer debended settings.
                GXManufacturerCollection Manufacturers = new GXManufacturerCollection();
                GXManufacturerCollection.ReadManufacturerSettings(Manufacturers);
                GXManufacturer man = Manufacturers.FindByIdentification(id);
                if (man == null)
                {
                    throw new Exception("Unknown manufacturer: " + id);
                }
                GXDLMSClient dlms = new GXDLMSClient();
                //Update Obis code list so we can get right descriptions to the objects.
                dlms.ObisCodes = man.ObisCodes;

                List<IAM.DLMSSite> DlmsSites = null;
                IAM.ArrayOfDLMSSite aods = null;

                XmlSerializer y = new XmlSerializer(typeof(IAM.ArrayOfDLMSSite));
                if (File.Exists(sitesMapPath))
                {
                    try
                    {
                        using (Stream stream = File.Open(sitesMapPath, FileMode.Open))
                        {
                            TraceLine(logFile, "Get configured sites map from file.");
                            aods = y.Deserialize(stream) as IAM.ArrayOfDLMSSite;
                            DlmsSites = aods.DLMSSite;
                            stream.Close();
                        }

                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
                else
                {
                    TraceLine(logFile, "Error. SitesMap file not found.");
                    return;
                }

                List<Type> extraTypes = new List<Type>(Gurux.DLMS.GXDLMSClient.GetObjectTypes());
                extraTypes.Add(typeof(GXDLMSAttributeSettings));
                extraTypes.Add(typeof(GXDLMSAttribute));
                //TraceLine(logFile, "Memory32: " + GC.GetTotalMemory(true));
                XmlSerializer x = new XmlSerializer(typeof(GXDLMSObjectCollection), extraTypes.ToArray());
                //You can save association view, but make sure that it is not change.
                //Save Association view to the cache so it is not needed to retrieve every time.
                extraTypes.Clear();

                foreach (IAM.DLMSSite site in DlmsSites) //
                {
                    site.DataProcessing.EnergyPeriodDateTime = DateTime.MinValue;
                    site.DataProcessing.PowerPeriodDateTime = DateTime.MinValue;
                }

                //bool keyAvailable = false;
                DateTime startTime;
                FileInfo infoFileSite = new FileInfo(sitesMapPath);
                DateTime lastWriteMapFile = infoFileSite.LastWriteTime;

                do
                {
                    try
                    {
                        FileInfo f = new FileInfo(logFileName); //output log file
                        if (f.Length > maxLogFileSize)
                        {
                            logFile.Flush();
                            logFile.Close();
                            File.Delete(rotatedLogFileName);
                            File.Move(logFileName, rotatedLogFileName);
                            logFile = new StreamWriter(File.Open(logFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite));
                        }

                        infoFileSite.Refresh();
                        if (infoFileSite.LastWriteTime != lastWriteMapFile)
                        {
                            try
                            {
                                using (Stream stream = File.Open(sitesMapPath, FileMode.Open))
                                {
                                    TraceLine(logFile, "Get updated sites map from file.");
                                    aods = y.Deserialize(stream) as IAM.ArrayOfDLMSSite;
                                    DlmsSites = aods.DLMSSite;
                                    stream.Close();

                                    lastWriteMapFile = infoFileSite.LastWriteTime;
                                }

                            }
                            catch (Exception ex)
                            {
                                throw ex;
                            }

                        }

                        startTime = DateTime.Now;
                        TraceLine(logFile, "Start new iteration");
                        foreach (IAM.DLMSSite site in DlmsSites) //cycle for each remote meter (listed in the sitemap.xml)
                        {
                            TraceLine(logFile, "Now processing: " + site.Name); //current remote meter
                            if (!site.Enabled)
                            {
                                TraceLine(logFile, "Disabled: skip to next");
                                continue;
                            }
                            try
                            {
                                host = site.Device.Host; //ip address of the current remote meter
                                port = site.Device.Port;
                                if (site.Device.Manufacturer != "")
                                    id = site.Device.Manufacturer.ToLower();
                                if (site.Device.Protocol != "")
                                    iec = site.Device.Protocol.ToLower() == "dlms";
                                if (media is GXNet)
                                {
                                    /*Gurux.Net.GXNet*/
                                    net = media as GXNet;
                                    net.Port = Convert.ToInt32(port);
                                    net.HostName = host;
                                    net.Protocol = Gurux.Net.NetworkType.Tcp;
                                }
                                comm = new GXCommunicatation(dlms, media, iec, auth, pw);
                                comm.Trace = trace;
                                TraceLine(logFile, "Initializing Network connection.");
                                comm.InitializeConnection(man);
                            }
                            catch (Exception ex)
                            {
                                TraceLine(logFile, "Error. " + ex.Message);
                                if (comm != null)
                                {
                                    comm.Close();
                                }
                                continue;
                            }
                            GXDLMSObjectCollection objects = null;

                            string meterPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) +  "\\" +host.Replace('.', '_') + "_" + port.ToString() + ".xml";

                            if (File.Exists(meterPath)) //list of OBIS objects for remote meter
                            {
                                try
                                {
                                    using (Stream stream = File.Open(meterPath, FileMode.Open))
                                    {
                                        TraceLine(logFile, "Get available objects from the cache.");
                                        objects = x.Deserialize(stream) as GXDLMSObjectCollection;
                                        stream.Close();
                                    }

                                }
                                catch (Exception ex)
                                {
                                    if (File.Exists(meterPath))
                                    {
                                        File.Delete(meterPath);
                                    }
                                    throw ex;
                                }
                            }
                            else
                            {
                                TraceLine(logFile, "Get available objects from the device.");
                                objects = comm.GetAssociationView();

                                // Save to file
                                try
                                {
                                    using (Stream stream = File.Open(meterPath, FileMode.Create))
                                    {
                                        TextWriter writer = new StreamWriter(stream);
                                        x.Serialize(writer, objects);
                                        writer.Close();
                                        stream.Close();
                                    }
                                    TraceLine(logFile, "Available objects saved to the cache.");

                                }
                                catch (Exception ex)
                                {
                                    if (File.Exists(meterPath))
                                    {
                                        File.Delete(meterPath);
                                    }
                                    throw ex;
                                }

                            }

                            // start remote meter reading
                            try
                            {
                                int EPeriod = 15;	// energy integration period
                                if (site.DataProcessing.EnergyPeriod != 0)
                                    EPeriod = site.DataProcessing.EnergyPeriod;
                                else
                                    site.DataProcessing.EnergyPeriod = EPeriod;

                                //if (EPeriod <= 0)
                                //    EPeriod = 15;

                                int PPeriod = 15;	// power integration period
                                if (site.DataProcessing.PowerPeriod != 0)
                                    PPeriod = site.DataProcessing.PowerPeriod;
                                else
                                    site.DataProcessing.PowerPeriod = PPeriod;

                                //if (PPeriod <= 0)
                                //    PPeriod = 15;

                                DateTime now = DateTime.Now;
                                DateTime nowRnd = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute / EPeriod * EPeriod, 0);

                                if (site.DataProcessing.EnergyPeriodDateTime == DateTime.MinValue)
                                {
                                    site.DataProcessing.EnergyPeriodDateTime = now;
                                    TraceLine(logFile, "Initialize energy period from null.");
                                }

                                // default OBIS codes for energies
                                string AEP = "1.0.1.8.0.255";
                                string AEM = "1.0.2.8.0.255";
                                string REP = "1.0.3.8.0.255";
                                string REM = "1.0.4.8.0.255";

                                if (!string.IsNullOrEmpty(site.ArrayOfOBIS.DataObjects.ActiveEnergyP)) //plus = absorbed energy
                                    AEP = site.ArrayOfOBIS.DataObjects.ActiveEnergyP;
                                if (!string.IsNullOrEmpty(site.ArrayOfOBIS.DataObjects.ActiveEnergyM)) //minus = supplied energy
                                    AEM = site.ArrayOfOBIS.DataObjects.ActiveEnergyM;
                                if (!string.IsNullOrEmpty(site.ArrayOfOBIS.DataObjects.ReactiveEnergyP)) //plus = absorbed energy
                                    REP = site.ArrayOfOBIS.DataObjects.ReactiveEnergyP;
                                if (!string.IsNullOrEmpty(site.ArrayOfOBIS.DataObjects.ReactiveEnergyM)) //minus = supplied energy
                                    REM = site.ArrayOfOBIS.DataObjects.ReactiveEnergyM;

                                GXDLMSObject aepObj = objects.FindByLN(ObjectType.Register, AEP);
                                if (aepObj == null)
                                    throw new System.InvalidOperationException(string.Format("Error: Active Energy Positive Object not defined for site {0}.", site.Name));
                                GXDLMSObject aemObj = objects.FindByLN(ObjectType.Register, AEM);
                                if (aemObj == null)
                                    throw new System.InvalidOperationException(string.Format("Active Energy Negative Object not defined for site {0}.", site.Name));
                                GXDLMSObject repObj = objects.FindByLN(ObjectType.Register, REP);
                                if (repObj == null)
                                    throw new System.InvalidOperationException(string.Format("Reactive Energy Positive Object not defined for site {0}.", site.Name));
                                GXDLMSObject remObj = objects.FindByLN(ObjectType.Register, REM);
                                if (remObj == null)
                                    throw new System.InvalidOperationException(string.Format("Reactive Energy Negative Object not defined for site {0}.", site.Name));

                                Regex regex = new Regex(@"^Scaler:(.*) Unit:(.*)$");
                                double scaler = 1;

                                object value = comm.Read(aepObj, 2);
                                string scalerAttr = (string)comm.Read(aepObj, 3);
                                Match match = regex.Match(scalerAttr);
                                if (match.Groups.Count >= 2)
                                    scaler = double.Parse(match.Groups[1].Value);
                                double ActiveEnergyP = double.Parse(value.ToString()) * scaler;
                                TraceLine(logFile, "Positive Active Energy reading completed.");

                                value = comm.Read(aemObj, 2);
                                scalerAttr = (string)comm.Read(aemObj, 3);
                                match = regex.Match(scalerAttr);
                                if (match.Groups.Count >= 2)
                                    scaler = double.Parse(match.Groups[1].Value);
                                double ActiveEnergyM = double.Parse(value.ToString()) * scaler;
                                TraceLine(logFile, "Negative Active Energy reading completed.");

                                value = comm.Read(repObj, 2);
                                scalerAttr = (string)comm.Read(repObj, 3);
                                match = regex.Match(scalerAttr);
                                if (match.Groups.Count >= 2)
                                    scaler = double.Parse(match.Groups[1].Value);
                                double ReactiveEnergyP = double.Parse(value.ToString()) * scaler;
                                TraceLine(logFile, "Positive Reactive Energy reading completed.");

                                value = comm.Read(remObj, 2);
                                scalerAttr = (string)comm.Read(remObj, 3);
                                match = regex.Match(scalerAttr);
                                if (match.Groups.Count >= 2)
                                    scaler = double.Parse(match.Groups[1].Value);
                                double ReactiveEnergyM = double.Parse(value.ToString()) * scaler;
                                TraceLine(logFile, "Negative Reactive Energy reading completed.");

                                // end of remote meter reading

                                if (site.DataProcessing.ActiveEnergyPStart == 0)
                                    site.DataProcessing.ActiveEnergyPStart = ActiveEnergyP;
                                site.DataProcessing.ActiveEnergyPCurrent = ActiveEnergyP;

                                if (site.DataProcessing.ActiveEnergyMStart == 0)
                                    site.DataProcessing.ActiveEnergyMStart = ActiveEnergyM;
                                site.DataProcessing.ActiveEnergyMCurrent = ActiveEnergyM;

                                if (site.DataProcessing.ReactiveEnergyPStart == 0)
                                    site.DataProcessing.ReactiveEnergyPStart = ReactiveEnergyP;
                                site.DataProcessing.ReactiveEnergyPCurrent = ReactiveEnergyP;

                                if (site.DataProcessing.ReactiveEnergyMStart == 0)
                                    site.DataProcessing.ReactiveEnergyMStart = ReactiveEnergyM;
                                site.DataProcessing.ReactiveEnergyMCurrent = ReactiveEnergyM;

                                DateTime tStart = new DateTime(site.DataProcessing.EnergyPeriodDateTime.Year, site.DataProcessing.EnergyPeriodDateTime.Month, site.DataProcessing.EnergyPeriodDateTime.Day, site.DataProcessing.EnergyPeriodDateTime.Hour, site.DataProcessing.EnergyPeriodDateTime.Minute / EPeriod * EPeriod, 0);
                                TimeSpan ts = now.Subtract(tStart);

                                if (EPeriod > 0)		// if energy recording enabled
                                {
                                    if (((ts.Hours * 60) + ts.Minutes) >= EPeriod)  // if end of period
                                    {
                                        ts = now.Subtract(site.DataProcessing.EnergyPeriodDateTime);
                                        double ratio = (double)((ts.Hours * 3600) + (ts.Minutes * 60) + ts.Seconds) / (EPeriod * 60);
                                        if (ratio > 0.9) ratio = 1;
                                        ratio = Math.Round(ratio, 2);
                                        TraceLine(logFile, string.Format("End of integration energy period (ratio = {0})", ratio));

                                        double deltaActiveEnergyP = site.DataProcessing.ActiveEnergyPCurrent - site.DataProcessing.ActiveEnergyPStart;
                                        double deltaActiveEnergyM = site.DataProcessing.ActiveEnergyMCurrent - site.DataProcessing.ActiveEnergyMStart;

                                        double deltaReactiveEnergyP = site.DataProcessing.ReactiveEnergyPCurrent - site.DataProcessing.ReactiveEnergyPStart;
                                        double deltaReactiveEnergyM = site.DataProcessing.ReactiveEnergyMCurrent - site.DataProcessing.ReactiveEnergyMStart;

                                        if (deltaActiveEnergyP > deltaActiveEnergyM)	// quadrants prevalent: I or IV
                                        {
                                            PublishEnergy(site, nowRnd, deltaActiveEnergyP, deltaActiveEnergyM, deltaReactiveEnergyP, 0, 0, deltaReactiveEnergyM, ratio, logFile);
                                        }
                                        else  // quadrants prevalent: II or III
                                        {
                                            PublishEnergy(site, nowRnd, deltaActiveEnergyP, deltaActiveEnergyM, 0, deltaReactiveEnergyP, deltaReactiveEnergyM, 0, ratio, logFile);
                                        }

                                        site.DataProcessing.EnergyPeriodDateTime = now;
                                        site.DataProcessing.ActiveEnergyPStart = ActiveEnergyP;
                                        site.DataProcessing.ActiveEnergyMStart = ActiveEnergyM;
                                        site.DataProcessing.ReactiveEnergyPStart = ReactiveEnergyP;
                                        site.DataProcessing.ReactiveEnergyMStart = ReactiveEnergyM;
                                    }
                                }

                                if (site.DataProcessing.ActivePowerPStart == 0)
                                    site.DataProcessing.ActivePowerPStart = ActiveEnergyP;
                                site.DataProcessing.ActivePowerPCurrent = ActiveEnergyP;

                                if (site.DataProcessing.ActivePowerMStart == 0)
                                    site.DataProcessing.ActivePowerMStart = ActiveEnergyM;
                                site.DataProcessing.ActivePowerMCurrent = ActiveEnergyM;

                                if (site.DataProcessing.ReactivePowerPStart == 0)
                                    site.DataProcessing.ReactivePowerPStart = ReactiveEnergyP;
                                site.DataProcessing.ReactivePowerPCurrent = ReactiveEnergyP;

                                if (site.DataProcessing.ReactivePowerMStart == 0)
                                    site.DataProcessing.ReactivePowerMStart = ReactiveEnergyM;
                                site.DataProcessing.ReactivePowerMCurrent = ReactiveEnergyM;

                                tStart = new DateTime(site.DataProcessing.PowerPeriodDateTime.Year, site.DataProcessing.PowerPeriodDateTime.Month, site.DataProcessing.PowerPeriodDateTime.Day, site.DataProcessing.PowerPeriodDateTime.Hour, site.DataProcessing.PowerPeriodDateTime.Minute / PPeriod * PPeriod, 0);
                                ts = now.Subtract(tStart);

                                if (PPeriod > 0)		// if power recording enabled
                                {
                                    if (((ts.Hours * 60) + ts.Minutes) >= PPeriod)  // if end of period
                                    {
                                        ts = now.Subtract(site.DataProcessing.PowerPeriodDateTime);
                                        double ratio = (double)((ts.Hours * 3600) + (ts.Minutes * 60) + ts.Seconds) / (PPeriod * 60);
                                        if (ratio > 0.9) ratio = 1;
                                        ratio = Math.Round(ratio, 2);
                                        TraceLine(logFile, string.Format("End of integration power period (ratio = {0})", ratio));

                                        double deltaActivePowerP = (site.DataProcessing.ActivePowerPCurrent - site.DataProcessing.ActivePowerPStart) / PPeriod * 60;
                                        double deltaActivePowerM = (site.DataProcessing.ActivePowerMCurrent - site.DataProcessing.ActivePowerMStart) / PPeriod * 60;

                                        double deltaReactivePowerP = (site.DataProcessing.ReactivePowerPCurrent - site.DataProcessing.ReactivePowerPStart) / PPeriod * 60;
                                        double deltaReactivePowerM = (site.DataProcessing.ReactivePowerMCurrent - site.DataProcessing.ReactivePowerMStart) / PPeriod * 60;

                                        // since ZXF meter has no capability to supply Q1-Q4 (but only 2 quadrants), we calculate Q1, Q2, Q3, Q4 here

                                        if (deltaActivePowerP > deltaActivePowerM)	// quadrants prevalent: I or IV
                                        {
                                            PublishPower(site, nowRnd, deltaActivePowerP, deltaActivePowerM, deltaReactivePowerP, 0, 0, deltaReactivePowerM, ratio, logFile);
                                        }
                                        else  // quadrants prevalent: II or III
                                        {
                                            PublishPower(site, nowRnd, deltaActivePowerP, deltaActivePowerM, 0, deltaReactivePowerP, deltaReactivePowerM, 0, ratio, logFile);
                                        }

                                        //

                                        site.DataProcessing.PowerPeriodDateTime = now;
                                        site.DataProcessing.ActivePowerPStart = ActiveEnergyP;
                                        site.DataProcessing.ActivePowerMStart = ActiveEnergyM;
                                        site.DataProcessing.ReactivePowerPStart = ReactiveEnergyP;
                                        site.DataProcessing.ReactivePowerMStart = ReactiveEnergyM;
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                TraceLine(logFile, "Error. " + ex.Message);
                                if (comm != null)
                                {
                                    comm.Close();
                                }
                                continue;
                            }

            #if ZERO
                            foreach (GXDLMSObject it in objects)
                            {
                                if (!string.IsNullOrEmpty(site.ArrayOfOBIS.DataObjects.ActiveEnergyP))		// if is requested the ActiveEnergy+ obis code
                                {

                                    if (it.LogicalName == AEP)
                                    {
                                        try
                                        {
                                            object value = comm.Read(it, 2);
                                            string scalerAttr = (string)comm.Read(it, 3);

                                            Regex regex = new Regex(@"^Scaler:(.*) Unit:(.*)$");
                                            Match match = regex.Match(scalerAttr);

                                            double scaler = 1;
                                            if (match.Groups.Count >= 2)
                                                scaler = double.Parse(match.Groups[1].Value);

                                            double Energy = double.Parse(value.ToString()) * scaler;

                                            // First time initialize the value of initial energy
                                            if (site.DataProcessing.ActiveEnergyPStart == 0)
                                            {
                                                site.DataProcessing.ActiveEnergyPStart = Energy;
                                                TraceLine(logFile, "Initial ActiveEnergy+ : " + Energy + " Wh");
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            TraceLine(logFile, "Error. Failed to get ActiveEnergy+: " + ex.Message);
                                            //Continue reading.
                                        }

                                    }
                                }

                                // Read meter inst. values
                                if (!string.IsNullOrEmpty(site.ArrayOfOBIS.DataObjects.ActivePower))
                                {
                                    try
                                    {

                                        if (it.LogicalName == site.ArrayOfOBIS.DataObjects.ActivePower)
                                        {
                                            //Console.WriteLine(it.Name);
                                            object value = comm.Read(it, 2);
                                            string scalerAttr = (string)comm.Read(it, 3);

                                            Regex regex = new Regex(@"^Scaler:(.*) Unit:(.*)$");
                                            Match match = regex.Match(scalerAttr);

                                            double scaler = 1;
                                            if (match.Groups.Count >= 2)
                                                scaler = double.Parse(match.Groups[1].Value);

                                            double activePower = double.Parse(value.ToString()) * scaler;
                                            TraceLine(logFile, "Active Power: " + activePower + " W");

                                            int period = 15;
                                            if (site.DataProcessing.Period != 0)
                                            {
                                                period = site.DataProcessing.Period;
                                            }
                                            DateTime now = DateTime.Now;
                                            DateTime nowRnd = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute / period * period, 0);

                                            if (site.DataProcessing.IntervalDateTime.Ticks == 0)
                                            {
                                                site.DataProcessing.IntervalDateTime = nowRnd;
                                                site.DataProcessing.Count = 0;
                                                site.DataProcessing.Sum = 0;
                                                TraceLine(logFile, "Initialize period from null.");
                                            }
                                            else
                                            {
                                                long elapsedTicks = now.Ticks - site.DataProcessing.IntervalDateTime.Ticks;
                                                TimeSpan elapsedSpan = new TimeSpan(elapsedTicks);
                                                if (elapsedSpan.TotalMinutes >= period)  // if end of period
                                                {
                                                    // Round date to minute multiple of "period"
                                                    if (site.DataProcessing.Count > 0)    // compute avg quantities
                                                    {
                                                        TraceLine(logFile, "End of inst. readings integration period.");
                                                        double avgActivePower = site.DataProcessing.Sum / site.DataProcessing.Count;
                                                        site.DataProcessing.IntervalDateTime = nowRnd;
                                                        site.DataProcessing.Count = 0;
                                                        site.DataProcessing.Sum = 0;
                                                        //                                                    PublishReading(site, site.DataProcessing.IntervalDateTime.AddMinutes(period), avgActivePower, logFile);
                                                        PublishReading(site, site.DataProcessing.IntervalDateTime, avgActivePower, 0, 0, 0, 0, 0, logFile);
                                                    }
                                                    else
                                                    {
                                                        TraceLine(logFile, "Zero counts period: initialize only.");
                                                        site.DataProcessing.IntervalDateTime = nowRnd;
                                                        site.DataProcessing.Count = 0;
                                                        site.DataProcessing.Sum = 0;
                                                    }
                                                }
                                                site.DataProcessing.Sum += activePower;
                                                site.DataProcessing.Count++;
                                            }
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        TraceLine(logFile, "Error. Failed to get inst. readings: " + ex.Message);
                                        //Continue reading.
                                    }
                                }

                                //  Read load profiles
                                if (string.IsNullOrEmpty(site.ArrayOfOBIS.GenericProfileObjects.LoadProfile))
                                    continue;

                                if (it.LogicalName == site.ArrayOfOBIS.GenericProfileObjects.LoadProfile)
                                {
                                    //Console.WriteLine(it.Name);
                                    try
                                    {
                                        int period = 15;
                                        if (site.DataProcessing.ProfilePeriod != 0)
                                        {
                                            period = site.DataProcessing.ProfilePeriod;
                                        }

                                        DateTime now = DateTime.Now;
                                        DateTime nowRnd = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute / period * period, 0);
                                        long elapsedTicks = now.Ticks - site.DataProcessing.ProfileDateTime.Ticks;
                                        TimeSpan elapsedSpan = new TimeSpan(elapsedTicks);
                                        double totalMinutes = elapsedSpan.TotalMinutes;
                                        int maxDays = 1;
                                        if (totalMinutes > 1440 * maxDays)
                                        {  // max one week
                                            totalMinutes = 1440 * maxDays;
                                            site.DataProcessing.ProfileDateTime = nowRnd.AddMinutes(-totalMinutes);
                                        }
                                        if (totalMinutes >= period)  // if end of period
                                        {
                                            //Read from Profile Generic.
                                            object[] rows = comm.ReadRowsByRange(it, site.DataProcessing.ProfileDateTime, nowRnd, (it as GXDLMSProfileGeneric).CaptureObjects);
                                            StringBuilder sb = new StringBuilder();
                                            foreach (object[] row in rows)
                                            {
                                                object dto = row[0];
                                                DateTime dt;
                                                if (DateTime.TryParse(dto.ToString(), out dt))
                                                {
                                                    dt = dt.ToLocalTime();
                                                    row[0] = dt;
                                                }

                                                foreach (object cell in row)
                                                {
                                                    if (cell is byte[])
                                                    {
                                                        sb.Append(GXCommon.ToHex((byte[])cell, true));
                                                    }
                                                    else
                                                    {
                                                        sb.Append(Convert.ToString(cell));
                                                    }
                                                    sb.Append(" | ");
                                                }
                                                sb.Append("\r\n");
                                            }
                                            site.DataProcessing.ProfileDateTime = nowRnd;
                                            PublishProfile(site, site.DataProcessing.ProfileDateTime, sb, logFile);
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        TraceLine(logFile, "Error. Failed to get load profile: " + ex.Message);
                                        //Continue reading.
                                    }
                                }
                            }
            #endif
                            try
                            {
                                using (Stream stream = File.Open(sitesMapPath, FileMode.Create))
                                {
                                    TraceLine(logFile, "Save site map to file.");
                                    TextWriter writer = new StreamWriter(stream);
                                    y.Serialize(writer, aods);
                                    //                            aods = y.Deserialize(stream) as IAM.ArrayOfDLMSSite;
                                    stream.Close();

                                    infoFileSite.Refresh();
                                    lastWriteMapFile = infoFileSite.LastWriteTime;
                                }

                            }
                            catch (Exception ex)
                            {
                                throw ex;
                            }

                            TraceLine(logFile, "Disconnecting from the meter.");
                            comm.Close();
                            objects.Clear();
                        }
                    }
                    catch (Exception ex)
                    {
                        TraceLine(logFile, ex.Message);
                        if (comm != null)
                        {
                            comm.Close();
                        }
                        // Continue reading
                    }

                    logFile.Flush();

                    if (loopTime > 0)   // wait until next loop time
                    {
                        DateTime when = DateTime.Now;
                        int nextMinutes = (when.Minute / loopTime) * loopTime + loopTime;
                        DateTime nextTime = new DateTime(when.Year, when.Month, when.Day);
                        nextTime = nextTime.AddHours(when.Hour);
                        nextTime = nextTime.AddMinutes(nextMinutes);
                        int waitSeconds = (int)(new TimeSpan(nextTime.Ticks - when.Ticks).TotalSeconds);
                        waitSeconds++;
                        TraceLine(logFile, "Waiting for next loop (in "+waitSeconds+" sec.)...\r\n");
                        logFile.Flush();
                        do
                        {
                            Thread.Sleep(1000);
                            waitSeconds--;

                            //if (Environment.UserInteractive)
                            //    keyAvailable = Console.KeyAvailable;

                        } while ((waitSeconds > 0) && !keyAvailable && running);
                    }
                    Console.WriteLine("");

                    //if (Environment.UserInteractive)
                    //    keyAvailable = Console.KeyAvailable;

                } while (!keyAvailable && (loopTime != -1) && running);

                if (keyAvailable)
                {
                    TraceLine(logFile, "Program interrupted by user.");
                }
                else if (!running)
                {
                    TraceLine(logFile, "Service stopped.");
                }
                else
                {
                    TraceLine(logFile, "Single run ended.");
                    if (!Environment.UserInteractive)
                    {
                        logFile.Flush();
                        logFile.Close();
                        Environment.Exit(0);
                    }
                }
            }
            catch (Exception ex)
            {
                if (logFile != null)
                    TraceLine(logFile, ex.Message);

                if (comm != null)
                {
                    comm.Close();
                }
                Console.WriteLine("Error. " + ex.Message);
            }
            finally
            {
                logFile.Flush();
                logFile.Close();

                if (comm != null)
                {
                    comm.Close();
                }
                Console.WriteLine("Now stop.");
            }
        }
예제 #20
0
 /// <summary>
 ///  Ask Server sends the Certificate Signing Request (CSR) data.
 /// </summary>
 /// <param name="client">DLMS client that is used to generate action.</param>
 /// <param name="type">identifies the key pair for which the certificate will be requested.</param>
 /// <returns>Generated action.</returns>
 public byte[][] GenerateCertificate(GXDLMSClient client, CertificateType type)
 {
     return client.Method(this, 5, type, DataType.Enum);
 }
예제 #21
0
 /// <summary>
 /// Presets the time to a new value (preset_time) and defines a validity_interval within which the new time can be activated.
 /// </summary>
 /// <param name="presetTime"></param>
 /// <param name="validityIntervalStart"></param>
 /// <param name="validityIntervalEnd"></param>
 /// <returns></returns>
 public byte[][] PresetAdjustingTime(GXDLMSClient client, DateTime presetTime, DateTime validityIntervalStart, DateTime validityIntervalEnd)
 {
     GXByteBuffer buff = new GXByteBuffer();
     buff.Add((byte)DataType.Structure);
     buff.Add((byte)3);
     GXCommon.SetData(client.Settings, buff, DataType.OctetString, presetTime);
     GXCommon.SetData(client.Settings, buff, DataType.OctetString, validityIntervalStart);
     GXCommon.SetData(client.Settings, buff, DataType.OctetString, validityIntervalEnd);
     return client.Method(this, 5, buff.Array(), DataType.Array);
 }
예제 #22
0
 /// <summary>
 ///  Imports an X.509 v3 certificate of a public key.
 /// </summary>
 /// <param name="client">DLMS client that is used to generate action.</param>
 /// <param name="key">Public key.</param>
 /// <returns>Generated action.</returns>
 public byte[][] ImportCertificate(GXDLMSClient client, byte[] key)
 {
     return client.Method(this, 6, key, DataType.OctetString);
 }
 public GXDLMSCommunicator(GXDLMSDevice parent, Gurux.Common.IGXMedia media)
 {
     Parent = parent;
     Media = media;
     m_Cosem = new Gurux.DLMS.GXDLMSClient();
 }
예제 #24
0
 /// <summary>
 /// Removes X.509 v3 certificate from the server using serial number.
 /// </summary>
 /// <param name="client">DLMS client that is used to generate action.</param>
 /// <param name="serialNumber">Serial number.</param>
 /// <param name="issuer">Issuer.</param>
 /// <returns>Generated action.</returns>
 public byte[][] RemoveCertificateBySerial(GXDLMSClient client, byte[] serialNumber, byte[] issuer)
 {
     GXByteBuffer bb = new GXByteBuffer();
     bb.SetUInt8(DataType.Structure);
     bb.SetUInt8(2);
     //Add enum
     bb.SetUInt8(DataType.Enum);
     bb.SetUInt8(1);
     //Add certificate_identification_by_entity
     bb.SetUInt8(DataType.Structure);
     bb.SetUInt8(2);
     //serialNumber
     GXCommon.SetData(client.Settings, bb, DataType.OctetString, serialNumber);
     //issuer
     GXCommon.SetData(client.Settings, bb, DataType.OctetString, issuer);
     return client.Method(this, 8, bb.Array(), DataType.OctetString);
 }
예제 #25
0
 /// <summary>
 /// Sets the meter’s time to the nearest (+/-) quarter of an hour value (*:00, *:15, *:30, *:45).
 /// </summary>
 /// <returns></returns>
 public byte[][] AdjustToQuarter(GXDLMSClient client)
 {
     return client.Method(this, 1, 0, DataType.Int8);            
 }
예제 #26
0
 /// <summary>
 /// Sets the meter’s time to the nearest (+/-) starting point of a measuring period.
 /// </summary>
 /// <returns></returns>
 public byte[][] AdjustToMeasuringPeriod(GXDLMSClient client)
 {
     return client.Method(this, 2, 0, DataType.Int8);            
 }
예제 #27
0
 /// <summary>
 /// Sets the meter’s time to the nearest minute.
 /// If second_counter < 30 s, so second_counter is set to 0.
 /// If second_counter ³ 30 s, so second_counter is set to 0, and
 /// minute_counter and all depending clock values are incremented if necessary.
 /// </summary>
 /// <returns></returns>
 public byte[][] AdjustToMinute(GXDLMSClient client)
 {
     return client.Method(this, 3, 0, DataType.Int8);            
 }
예제 #28
0
 public byte[][] ImageBlockTransfer(GXDLMSClient client, byte[] imageBlockValue, out int ImageBlockCount)
 {
     ImageBlockCount = (int)(imageBlockValue.Length / ImageBlockSize);
     if (imageBlockValue.Length % ImageBlockSize != 0)
     {
         ++ImageBlockCount;
     }
     List<byte[]> packets = new List<byte[]>();
     for (int pos = 0; pos != ImageBlockCount; ++pos)
     {
         List<byte> data = new List<byte>();
         data.Add((byte)DataType.Structure);
         data.Add((byte)2);
         GXCommon.SetData(data, DataType.UInt32, pos);
         byte[] tmp;
         int bytes = (int)(imageBlockValue.Length - ((pos + 1) * ImageBlockSize));
         //If last packet
         if (bytes < 0)
         {
             bytes = (int)(imageBlockValue.Length - (pos * ImageBlockSize));
             tmp = new byte[bytes];
             Array.Copy(imageBlockValue, pos * ImageBlockSize, tmp, 0, bytes);
         }
         else
         {
             tmp = new byte[ImageBlockSize];
             Array.Copy(imageBlockValue, (pos * ImageBlockSize), tmp, 0, ImageBlockSize);
         }
         GXCommon.SetData(data, DataType.OctetString, tmp);
         packets.AddRange(client.Method(this, 2, data.ToArray(), DataType.Array));
     }
     return packets.ToArray();
 }
예제 #29
0
 /// <summary>
 /// This Method is used in conjunction with the preset_adjusting_time
 /// Method. If the meter’s time lies between validity_interval_start and
 /// validity_interval_end, then time is set to preset_time.
 /// </summary>
 /// <returns></returns>
 public byte[][] AdjustToPresetTime(GXDLMSClient client)
 {
     return client.Method(this, 4, 0, DataType.Int8);            
 }
예제 #30
0
 public byte[][] ImageActivate(GXDLMSClient client)
 {
     return client.Method(this, 4, 0, DataType.Int8);
 }
예제 #31
0
 /// <summary>
 /// Presets the time to a new value (preset_time) and defines a validity_interval within which the new time can be activated.
 /// </summary>
 /// <param name="presetTime"></param>
 /// <param name="validityIntervalStart"></param>
 /// <param name="validityIntervalEnd"></param>
 /// <returns></returns>
 public byte[][] PresetAdjustingTime(GXDLMSClient client, DateTime presetTime, DateTime validityIntervalStart, DateTime validityIntervalEnd)
 {
     List<byte> buff = new List<byte>();
     buff.Add((byte)DataType.Structure);
     buff.Add((byte)3);
     GXCommon.SetData(buff, DataType.DateTime, presetTime);
     GXCommon.SetData(buff, DataType.DateTime, validityIntervalStart);
     GXCommon.SetData(buff, DataType.DateTime, validityIntervalEnd);
     return client.Method(this, 5, buff.ToArray(), DataType.Array);            
 }
예제 #32
0
 /// <summary>
 /// Reset value.
 /// </summary>
 /// <returns></returns>
 public byte[][] Reset(GXDLMSClient client)
 {
     return client.Method(this, 1, (int)0);            
 }
예제 #33
0
 /// <summary>
 /// Activates the push process.
 /// </summary>
 /// <returns></returns>
 public byte[][] Activate(GXDLMSClient client)
 {
     return client.Method(this, 1, (byte)0);
 }