static void Main(string[] args) { IGXMedia media = null; GXCommunicatation comm = null; try { TextWriter logFile = new StreamWriter(File.Open("LogFile.txt", FileMode.Create)); //////////////////////////////////////// //Handle command line parameters. String sn, client = "", server = "", id = "", host = "", port = "", pw = ""; bool trace = false, iec = true; bool hdlc = true, ln = true; 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("/sn="))//Serial number. { sn = item.Replace("/sn=", ""); } else if (string.Compare(item, "/wrapper", true) == 0)//Wrapper is used. { hdlc = false; } else if (item.StartsWith("/r="))//referencing { id = item.Replace("/r=", ""); } else if (item.StartsWith("/m="))//Manufacturer { id = item.Replace("/m=", ""); } else if (item.StartsWith("/client="))//Client address { client = item.Replace("/client=", ""); } else if (item.StartsWith("/server="))//Server address { server = item.Replace("/server=", ""); } else if (item.StartsWith("/h=")) //Host { host = item.Replace("/h=", ""); } 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 { ShowHelp(); return; } } if (string.IsNullOrEmpty(id) || string.IsNullOrEmpty(port) || (media is GXNet && string.IsNullOrEmpty(host))) { ShowHelp(); return; } //////////////////////////////////////// //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 depended settings. GXManufacturerCollection Manufacturers = new GXManufacturerCollection(); GXManufacturerCollection.ReadManufacturerSettings(Manufacturers); GXManufacturer man = Manufacturers.FindByIdentification(id); if (man == null) { throw new Exception("Unknown manufacturer: " + id); } GXDLMSSecureClient dlms = new GXDLMSSecureClient(); //Update Obis code list so we can get right descriptions to the objects. dlms.CustomObisCodes = man.ObisCodes; comm = new GXCommunicatation(dlms, media, iec, auth, pw); comm.Trace = trace; comm.InitializeConnection(man); GXDLMSObjectCollection objects = null; string path = host.Replace('.', '_') + "_" + port.ToString() + ".xml"; List<Type> extraTypes = new List<Type>(Gurux.DLMS.GXDLMSClient.GetObjectTypes()); extraTypes.Add(typeof(GXDLMSAttributeSettings)); extraTypes.Add(typeof(GXDLMSAttribute)); 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. /* if (File.Exists(path)) { try { using (Stream stream = File.Open(path, FileMode.Open)) { Console.WriteLine("Get available objects from the cache."); objects = x.Deserialize(stream) as GXDLMSObjectCollection; stream.Close(); } } catch (Exception ex) { if (File.Exists(path)) { File.Delete(path); } throw ex; } } else */ { Console.WriteLine("Get available objects from the device."); objects = comm.GetAssociationView(); GXDLMSObjectCollection objs = objects.GetObjects(new ObjectType[] { ObjectType.Register, ObjectType.ExtendedRegister, ObjectType.DemandRegister }); Console.WriteLine("Read scalers and units from the device."); List<KeyValuePair<GXDLMSObject, int>> list = new List<KeyValuePair<GXDLMSObject, int>>(); try { foreach (GXDLMSObject it in objs) { if (it is GXDLMSRegister) { list.Add(new KeyValuePair<GXDLMSObject, int>(it, 3)); } if (it is GXDLMSDemandRegister) { list.Add(new KeyValuePair<GXDLMSObject, int>(it, 4)); } } comm.ReadList(list); } catch { //If this fails meter is not supporting reading read by list method. //Read values one by one. foreach (GXDLMSObject it in objs) { try { if (it is GXDLMSRegister) { Console.WriteLine(it.Name); comm.Read(it, 3); } if (it is GXDLMSDemandRegister) { Console.WriteLine(it.Name); comm.Read(it, 4); } } catch { //Actaric SL7000 can return error here. Continue reading. } } } //Read Profile Generic columns first. foreach (GXDLMSObject it in objects.GetObjects(ObjectType.ProfileGeneric)) { try { Console.WriteLine(it.Name); comm.Read(it, 3); GXDLMSObject[] cols = (it as GXDLMSProfileGeneric).GetCaptureObject(); TraceLine(logFile, "Profile Generic " + it.Name + " Columns:"); StringBuilder sb = new StringBuilder(); bool First = true; foreach (GXDLMSObject col in cols) { if (!First) { sb.Append(" | "); } First = false; sb.Append(col.Name); sb.Append(" "); sb.Append(col.Description); } TraceLine(logFile, sb.ToString()); } catch (Exception ex) { TraceLine(logFile, "Err! Failed to read columns:" + ex.Message); //Continue reading. } } try { using (Stream stream = File.Open(path, FileMode.Create)) { TextWriter writer = new StreamWriter(stream); x.Serialize(writer, objects); writer.Close(); stream.Close(); } } catch (Exception ex) { if (File.Exists(path)) { File.Delete(path); } throw ex; } Console.WriteLine("--- Available objects ---"); foreach (GXDLMSObject it in objects) { Console.WriteLine(it.Name + " " + it.Description); } } foreach (GXDLMSObject it in objects) { // Profile generics are read later because they are special cases. // (There might be so lots of data and we so not want waste time to read all the data.) if (it is GXDLMSProfileGeneric) { continue; } if (!(it is IGXDLMSBase)) { //If interface is not implemented. //Example manufacturer spesific interface. Console.WriteLine("Unknown Interface: " + it.ObjectType.ToString()); continue; } TraceLine(logFile, "-------- Reading " + it.GetType().Name + " " + it.Name + " " + it.Description); foreach (int pos in (it as IGXDLMSBase).GetAttributeIndexToRead()) { try { object val = comm.Read(it, pos); //If data is array. if (val is byte[]) { val = GXCommon.ToHex((byte[])val, true); } else if (val is Array) { string str = ""; for (int pos2 = 0; pos2 != (val as Array).Length; ++pos2) { if (str != "") { str += ", "; } if ((val as Array).GetValue(pos2) is byte[]) { str += GXCommon.ToHex((byte[])(val as Array).GetValue(pos2), true); } else { str += (val as Array).GetValue(pos2).ToString(); } } val = str; } else if (val is System.Collections.IList) { string str = "["; bool empty = true; foreach (object it2 in val as System.Collections.IList) { if (!empty) { str += ", "; } empty = false; if (it2 is byte[]) { str += GXCommon.ToHex((byte[])it2, true); } else { str += it2.ToString(); } } str += "]"; val = str; } TraceLine(logFile, "Index: " + pos + " Value: " + val); } catch (Exception ex) { TraceLine(logFile, "Error! Index: " + pos + " " + ex.Message); } } } //Find profile generics and read them. foreach (GXDLMSObject it in objects.GetObjects(ObjectType.ProfileGeneric)) { TraceLine(logFile, "-------- Reading " + it.GetType().Name + " " + it.Name + " " + it.Description); long entriesInUse = Convert.ToInt64(comm.Read(it, 7)); long entries = Convert.ToInt64(comm.Read(it, 8)); TraceLine(logFile, "Entries: " + entriesInUse + "/" + entries); //If there are no columns or rows. if (entriesInUse == 0 || (it as GXDLMSProfileGeneric).CaptureObjects.Count == 0) { continue; } try { //Read first row from Profile Generic. object[] rows = comm.ReadRowsByEntry(it as GXDLMSProfileGeneric, 1, 1); StringBuilder sb = new StringBuilder(); foreach (object[] row in rows) { 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"); } Trace(logFile, sb.ToString()); } catch (Exception ex) { TraceLine(logFile, "Error! Failed to read first row: " + ex.Message); //Continue reading. } try { //Read last day from Profile Generic. object[] rows = comm.ReadRowsByRange(it as GXDLMSProfileGeneric, DateTime.Now.Date, DateTime.MaxValue); StringBuilder sb = new StringBuilder(); foreach (object[] row in rows) { 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"); } Trace(logFile, sb.ToString()); } catch (Exception ex) { TraceLine(logFile, "Error! Failed to read last day: " + ex.Message); //Continue reading. } } logFile.Flush(); logFile.Close(); } catch (Exception ex) { if (comm != null) { comm.Close(); } Console.WriteLine(ex.Message); if (!System.Diagnostics.Debugger.IsAttached) { Console.ReadKey(); } } finally { if (comm != null) { comm.Close(); } if (System.Diagnostics.Debugger.IsAttached) { Console.WriteLine("Ended. Press any key to continue."); Console.ReadKey(); } } }
public DevicePropertiesForm(GXManufacturerCollection manufacturers, GXDLMSDevice dev) { try { InitializeComponent(); NetProtocolCB.Items.AddRange(new object[] { NetworkType.Tcp, NetworkType.Udp }); this.ServerAddressTypeCB.SelectedIndexChanged += new System.EventHandler(this.ServerAddressTypeCB_SelectedIndexChanged); NetworkSettingsGB.Width = this.Width - NetworkSettingsGB.Left; SerialSettingsGB.Bounds = TerminalSettingsGB.Bounds = NetworkSettingsGB.Bounds; ServerAddressTypeCB.DrawMode = AuthenticationCB.DrawMode = DrawMode.OwnerDrawFixed; Manufacturers = manufacturers; //OK button is not enabled if there are no manufacturers. if (Manufacturers.Count == 0) { OKBtn.Enabled = false; } //Show supported services tab only when they are read. if (dev == null || dev.Comm.client.SNSettings == null && dev.Comm.client.LNSettings == null) { DeviceTab.TabPages.Remove(SupportedServicesTab); } else { object settings = null; if (dev.Comm.client.UseLogicalNameReferencing) { settings = dev.Comm.client.LNSettings; } else { settings = dev.Comm.client.SNSettings; } if (settings != null) { SupportedServicesGrid.SelectedObject = settings; foreach (PropertyDescriptor it in TypeDescriptor.GetProperties(settings)) { ReadOnlyAttribute att = (ReadOnlyAttribute)it.Attributes[typeof(ReadOnlyAttribute)]; if (att != null) { FieldInfo[] f = att.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance); f[0].SetValue(att, true); } } } } Device = dev; StartProtocolCB.Items.Add(StartProtocolType.IEC); StartProtocolCB.Items.Add(StartProtocolType.DLMS); int pos = 0; foreach (GXManufacturer it in Manufacturers) { int index = this.ManufacturerCB.Items.Add(it); if (it.Name == GXDLMSDirector.Properties.Settings.Default.SelectedManufacturer) { pos = index; } } if (Device == null) { Device = new GXDLMSDevice(null); //Select first manufacturer. if (Manufacturers.Count != 0) { ManufacturerCB.SelectedIndex = pos; } } else { foreach (GXManufacturer it in this.ManufacturerCB.Items) { if (string.Compare(it.Identification, Device.Manufacturer, true) == 0) { this.ManufacturerCB.SelectedItem = it; break; } } this.VerboseModeCB.Checked = dev.Verbose; this.NameTB.Text = dev.Name; SelectedMedia = dev.Media; UseRemoteSerialCB.Checked = Device.UseRemoteSerial; StartProtocolCB.SelectedItem = Device.StartProtocol; PhysicalServerAddressTB.Value = Convert.ToDecimal(Device.PhysicalAddress); LogicalServerAddressTB.Value = Convert.ToDecimal(Device.LogicalAddress); this.ClientAddTB.Value = Convert.ToDecimal(Convert.ToUInt32(Device.ClientAddress)); WaitTimeTB.Value = Device.WaitTime; } ManufacturerCB.DrawMode = MediasCB.DrawMode = DrawMode.OwnerDrawFixed; Gurux.Net.GXNet net = new Gurux.Net.GXNet(); //Initialize network settings. if (SelectedMedia is GXNet) { this.MediasCB.Items.Add(SelectedMedia); net.Protocol = Gurux.Net.NetworkType.Tcp; this.HostNameTB.Text = ((GXNet)SelectedMedia).HostName; this.PortTB.Text = ((GXNet)SelectedMedia).Port.ToString(); NetProtocolCB.SelectedItem = ((GXNet)SelectedMedia).Protocol; } else { NetProtocolCB.SelectedItem = net.Protocol = Gurux.Net.NetworkType.Tcp; this.MediasCB.Items.Add(net); } //Set maximum baud rate. GXSerial serial = new GXSerial(); foreach (int it in serial.GetAvailableBaudRates("")) { if (it != 0) { MaximumBaudRateCB.Items.Add(it); } } if (Device.MaximumBaudRate == 0) { UseMaximumBaudRateCB.Checked = false; UseMaximumBaudRateCB_CheckedChanged(null, null); } else { UseMaximumBaudRateCB.Checked = true; this.MaximumBaudRateCB.SelectedItem = Device.MaximumBaudRate; } if (SelectedMedia is GXSerial) { this.MediasCB.Items.Add(SelectedMedia); string[] ports = GXSerial.GetPortNames(); this.SerialPortCB.Items.AddRange(ports); if (ports.Length != 0) { this.SerialPortCB.SelectedItem = ((GXSerial)SelectedMedia).PortName; } } else { //Initialize serial settings. string[] ports = GXSerial.GetPortNames(); this.SerialPortCB.Items.AddRange(ports); if (ports.Length != 0) { serial.PortName = ports[0]; } if (((GXManufacturer)ManufacturerCB.SelectedItem).StartProtocol == StartProtocolType.DLMS) { serial.BaudRate = 9600; serial.DataBits = 8; serial.Parity = Parity.None; serial.StopBits = StopBits.One; } else { serial.BaudRate = 300; serial.DataBits = 7; serial.Parity = Parity.Even; serial.StopBits = StopBits.One; } this.MediasCB.Items.Add(serial); } if (SelectedMedia is Gurux.Terminal.GXTerminal) { this.MediasCB.Items.Add(SelectedMedia); string[] ports = GXTerminal.GetPortNames(); this.TerminalPortCB.Items.AddRange(ports); if (ports.Length != 0) { this.TerminalPortCB.SelectedItem = ((Gurux.Terminal.GXTerminal)SelectedMedia).PortName; } this.TerminalPhoneNumberTB.Text = ((Gurux.Terminal.GXTerminal)SelectedMedia).PhoneNumber; } else { //Initialize terminal settings. Gurux.Terminal.GXTerminal termial = new Gurux.Terminal.GXTerminal(); string[] ports = GXTerminal.GetPortNames(); this.TerminalPortCB.Items.AddRange(ports); if (ports.Length != 0) { termial.PortName = ports[0]; } termial.BaudRate = 9600; termial.DataBits = 8; termial.Parity = Parity.None; termial.StopBits = StopBits.One; this.TerminalPhoneNumberTB.Text = termial.PhoneNumber; //termial.InitializeCommands = "AT+CBST=71,0,1\r\n"; this.MediasCB.Items.Add(termial); } //Select first media if medis is not selected. if (SelectedMedia == null) { SelectedMedia = (Gurux.Common.IGXMedia)this.MediasCB.Items[0]; } this.MediasCB.SelectedItem = SelectedMedia; if (!string.IsNullOrEmpty(Device.Password)) { this.PasswordTB.Text = ASCIIEncoding.ASCII.GetString(CryptHelper.Decrypt(Device.Password, Password.Key)); } if (dev != null) { this.UseLNCB.Checked = dev.UseLogicalNameReferencing; } this.AuthenticationCB.SelectedIndexChanged += new System.EventHandler(this.AuthenticationCB_SelectedIndexChanged); bool bConnected = Device.Media != null && Device.Media.IsOpen; SerialPortCB.Enabled = AdvancedBtn.Enabled = ManufacturerCB.Enabled = MediasCB.Enabled = AuthenticationCB.Enabled = UseRemoteSerialCB.Enabled = OKBtn.Enabled = !bConnected; HostNameTB.ReadOnly = PortTB.ReadOnly = PasswordTB.ReadOnly = WaitTimeTB.ReadOnly = PhysicalServerAddressTB.ReadOnly = NameTB.ReadOnly = bConnected; } catch (Exception Ex) { GXDLMS.Common.Error.ShowError(this, Ex); } }
static void Main(string[] args) { IGXMedia media = null; GXCommunicatation comm = null; try { TextWriter logFile = new StreamWriter(File.Open("LogFile.txt", FileMode.Create)); //////////////////////////////////////// //Handle command line parameters. String id = "", host = "", port = "", pw = ""; bool trace = false, iec = true; 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("/h=")) //Host { host = item.Replace("/h=", ""); } 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 { ShowHelp(); return; } } if (string.IsNullOrEmpty(id) || string.IsNullOrEmpty(port) || (media is GXNet && string.IsNullOrEmpty(host))) { ShowHelp(); return; } //////////////////////////////////////// //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 depended 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.CustomObisCodes = man.ObisCodes; comm = new GXCommunicatation(dlms, media, iec, auth, pw); comm.Trace = trace; comm.InitializeConnection(man); GXDLMSObjectCollection objects = null; string path = host.Replace('.', '_') + "_" + port.ToString() + ".xml"; List <Type> extraTypes = new List <Type>(Gurux.DLMS.GXDLMSClient.GetObjectTypes()); extraTypes.Add(typeof(GXDLMSAttributeSettings)); extraTypes.Add(typeof(GXDLMSAttribute)); 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. /* * if (File.Exists(path)) * { * try * { * using (Stream stream = File.Open(path, FileMode.Open)) * { * Console.WriteLine("Get available objects from the cache."); * objects = x.Deserialize(stream) as GXDLMSObjectCollection; * stream.Close(); * } * } * catch (Exception ex) * { * if (File.Exists(path)) * { * File.Delete(path); * } * throw ex; * } * } * else */ { Console.WriteLine("Get available objects from the device."); objects = comm.GetAssociationView(); GXDLMSObjectCollection objs = objects.GetObjects(new ObjectType[] { ObjectType.Register, ObjectType.ExtendedRegister, ObjectType.DemandRegister }); Console.WriteLine("Read scalers and units from the device."); Thread.Sleep(1000); foreach (GXDLMSObject it in objs) { if (it is GXDLMSRegister) { Console.WriteLine(it.Name); comm.Read(it, 3); } if (it is GXDLMSDemandRegister) { Console.WriteLine(it.Name); comm.Read(it, 4); } } Thread.Sleep(1000); //Read Profile Generic columns first. foreach (GXDLMSObject it in objects.GetObjects(ObjectType.ProfileGeneric)) { try { Console.WriteLine(it.Name); comm.Read(it, 3); GXDLMSObject[] cols = (it as GXDLMSProfileGeneric).GetCaptureObject(); TraceLine(logFile, "Profile Generic " + it.Name + " Columns:"); StringBuilder sb = new StringBuilder(); bool First = true; foreach (GXDLMSObject col in cols) { if (!First) { sb.Append(" | "); } First = false; sb.Append(col.Name); sb.Append(" "); sb.Append(col.Description); } TraceLine(logFile, sb.ToString()); } catch (Exception ex) { TraceLine(logFile, "Err! Failed to read columns:" + ex.Message); //Continue reading. } } try { using (Stream stream = File.Open(path, FileMode.Create)) { TextWriter writer = new StreamWriter(stream); x.Serialize(writer, objects); writer.Close(); stream.Close(); } } catch (Exception ex) { if (File.Exists(path)) { File.Delete(path); } throw ex; } Console.WriteLine("--- Available objects ---"); foreach (GXDLMSObject it in objects) { Console.WriteLine(it.Name + " " + it.Description); } } Thread.Sleep(1000); foreach (GXDLMSObject it in objects) { // Profile generics are read later because they are special cases. // (There might be so lots of data and we so not want waste time to read all the data.) if (it is GXDLMSProfileGeneric) { continue; } if (!(it is IGXDLMSBase)) { //If interface is not implemented. //Example manufacturer spesific interface. Console.WriteLine("Unknown Interface: " + it.ObjectType.ToString()); continue; } TraceLine(logFile, "-------- Reading " + it.GetType().Name + " " + it.Name + " " + it.Description); foreach (int pos in (it as IGXDLMSBase).GetAttributeIndexToRead()) { try { object val = comm.Read(it, pos); //If data is array. if (val is byte[]) { val = GXCommon.ToHex((byte[])val, true); } else if (val is Array) { string str = ""; for (int pos2 = 0; pos2 != (val as Array).Length; ++pos2) { if (str != "") { str += ", "; } if ((val as Array).GetValue(pos2) is byte[]) { str += GXCommon.ToHex((byte[])(val as Array).GetValue(pos2), true); } else { str += (val as Array).GetValue(pos2).ToString(); } } val = str; } else if (val is System.Collections.IList) { string str = "["; bool empty = true; foreach (object it2 in val as System.Collections.IList) { if (!empty) { str += ", "; } empty = false; if (it2 is byte[]) { str += GXCommon.ToHex((byte[])it2, true); } else { str += it2.ToString(); } } str += "]"; val = str; } TraceLine(logFile, "Index: " + pos + " Value: " + val); } catch (Exception ex) { TraceLine(logFile, "Error! Index: " + pos + " " + ex.Message); } } } Thread.Sleep(1000); //Find profile generics and read them. foreach (GXDLMSObject it in objects.GetObjects(ObjectType.ProfileGeneric)) { TraceLine(logFile, "-------- Reading " + it.GetType().Name + " " + it.Name + " " + it.Description); long entriesInUse = Convert.ToInt64(comm.Read(it, 7)); long entries = Convert.ToInt64(comm.Read(it, 8)); TraceLine(logFile, "Entries: " + entriesInUse + "/" + entries); //If there are no columns or rows. if (entriesInUse == 0 || (it as GXDLMSProfileGeneric).CaptureObjects.Count == 0) { continue; } try { //Read first row from Profile Generic. object[] rows = comm.ReadRowsByEntry(it as GXDLMSProfileGeneric, 0, 1); StringBuilder sb = new StringBuilder(); foreach (object[] row in rows) { 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"); } Trace(logFile, sb.ToString()); } catch (Exception ex) { TraceLine(logFile, "Error! Failed to read first row: " + ex.Message); //Continue reading. } try { //Read last day from Profile Generic. object[] rows = comm.ReadRowsByRange(it as GXDLMSProfileGeneric, DateTime.Now.Date, DateTime.MaxValue); StringBuilder sb = new StringBuilder(); foreach (object[] row in rows) { 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"); } Trace(logFile, sb.ToString()); } catch (Exception ex) { TraceLine(logFile, "Error! Failed to read last day: " + ex.Message); //Continue reading. } } logFile.Flush(); logFile.Close(); } catch (Exception ex) { if (comm != null) { comm.Close(); } Console.WriteLine(ex.Message); if (!System.Diagnostics.Debugger.IsAttached) { Console.ReadKey(); } } finally { if (comm != null) { comm.Close(); } if (System.Diagnostics.Debugger.IsAttached) { Console.WriteLine("Ended. Press any key to continue."); Console.ReadKey(); } } }
public DevicePropertiesForm(GXManufacturerCollection manufacturers, GXDLMSDevice dev) { try { InitializeComponent(); SecurityCB.Items.AddRange(new object[] { Security.None, Security.Authentication, Security.Encryption, Security.AuthenticationEncryption }); NetProtocolCB.Items.AddRange(new object[] { NetworkType.Tcp, NetworkType.Udp }); this.ServerAddressTypeCB.SelectedIndexChanged += new System.EventHandler(this.ServerAddressTypeCB_SelectedIndexChanged); NetworkSettingsGB.Width = this.Width - NetworkSettingsGB.Left; SerialSettingsGB.Bounds = TerminalSettingsGB.Bounds = NetworkSettingsGB.Bounds; ServerAddressTypeCB.DrawMode = AuthenticationCB.DrawMode = DrawMode.OwnerDrawFixed; Manufacturers = manufacturers; //OK button is not enabled if there are no manufacturers. if (Manufacturers.Count == 0) { OKBtn.Enabled = false; } //Show supported services tab only when they are read. if (dev == null || dev.Comm.client.SNSettings == null && dev.Comm.client.LNSettings == null) { DeviceTab.TabPages.Remove(SupportedServicesTab); } else { object settings = null; if (dev.Comm.client.UseLogicalNameReferencing) { settings = dev.Comm.client.LNSettings; } else { settings = dev.Comm.client.SNSettings; } if (settings != null) { SupportedServicesGrid.SelectedObject = settings; foreach (PropertyDescriptor it in TypeDescriptor.GetProperties(settings)) { ReadOnlyAttribute att = (ReadOnlyAttribute)it.Attributes[typeof(ReadOnlyAttribute)]; if (att != null) { FieldInfo[] f = att.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance); f[0].SetValue(att, true); } } } } Device = dev; StartProtocolCB.Items.Add(StartProtocolType.IEC); StartProtocolCB.Items.Add(StartProtocolType.DLMS); int pos = 0; foreach (GXManufacturer it in Manufacturers) { int index = this.ManufacturerCB.Items.Add(it); if (it.Name == GXDLMSDirector.Properties.Settings.Default.SelectedManufacturer) { pos = index; } } if (Device == null) { Device = new GXDLMSDevice(null); //Select first manufacturer. if (Manufacturers.Count != 0) { ManufacturerCB.SelectedIndex = pos; } } else { foreach (GXManufacturer it in this.ManufacturerCB.Items) { if (string.Compare(it.Identification, Device.Manufacturer, true) == 0) { this.ManufacturerCB.SelectedItem = it; break; } } this.VerboseModeCB.Checked = dev.Verbose; this.NameTB.Text = dev.Name; SelectedMedia = dev.Media; UseRemoteSerialCB.Checked = Device.UseRemoteSerial; StartProtocolCB.SelectedItem = Device.StartProtocol; PhysicalServerAddressTB.Value = Convert.ToDecimal(Device.PhysicalAddress); LogicalServerAddressTB.Value = Convert.ToDecimal(Device.LogicalAddress); this.ClientAddTB.Value = Convert.ToDecimal(Convert.ToUInt32(Device.ClientAddress)); WaitTimeTB.Value = Device.WaitTime; SecurityCB.SelectedItem = dev.Security; SystemTitleTB.Text = dev.SystemTitle; BlockCipherKeyTB.Text = dev.BlockCipherKey; AuthenticationKeyTB.Text = dev.AuthenticationKey; UseUtcTimeZone.Checked = Device.UtcTimeZone; } ManufacturerCB.DrawMode = MediasCB.DrawMode = DrawMode.OwnerDrawFixed; Gurux.Net.GXNet net = new Gurux.Net.GXNet(); //Initialize network settings. if (SelectedMedia is GXNet) { this.MediasCB.Items.Add(SelectedMedia); net.Protocol = Gurux.Net.NetworkType.Tcp; this.HostNameTB.Text = ((GXNet)SelectedMedia).HostName; this.PortTB.Text = ((GXNet)SelectedMedia).Port.ToString(); NetProtocolCB.SelectedItem = ((GXNet)SelectedMedia).Protocol; } else { NetProtocolCB.SelectedItem = net.Protocol = Gurux.Net.NetworkType.Tcp; this.MediasCB.Items.Add(net); } //Set maximum baud rate. GXSerial serial = new GXSerial(); foreach (int it in serial.GetAvailableBaudRates("")) { if (it != 0) { MaximumBaudRateCB.Items.Add(it); } } if (Device.MaximumBaudRate == 0) { UseMaximumBaudRateCB.Checked = false; UseMaximumBaudRateCB_CheckedChanged(null, null); } else { UseMaximumBaudRateCB.Checked = true; this.MaximumBaudRateCB.SelectedItem = Device.MaximumBaudRate; } if (SelectedMedia is GXSerial) { this.MediasCB.Items.Add(SelectedMedia); string[] ports = GXSerial.GetPortNames(); this.SerialPortCB.Items.AddRange(ports); if (ports.Length != 0) { this.SerialPortCB.SelectedItem = ((GXSerial)SelectedMedia).PortName; } } else { //Initialize serial settings. string[] ports = GXSerial.GetPortNames(); this.SerialPortCB.Items.AddRange(ports); if (ports.Length != 0) { serial.PortName = ports[0]; } if (((GXManufacturer)ManufacturerCB.SelectedItem).StartProtocol == StartProtocolType.DLMS) { serial.BaudRate = 9600; serial.DataBits = 8; serial.Parity = Parity.None; serial.StopBits = StopBits.One; } else { serial.BaudRate = 300; serial.DataBits = 7; serial.Parity = Parity.Even; serial.StopBits = StopBits.One; } this.MediasCB.Items.Add(serial); } if (SelectedMedia is Gurux.Terminal.GXTerminal) { this.MediasCB.Items.Add(SelectedMedia); string[] ports = GXTerminal.GetPortNames(); this.TerminalPortCB.Items.AddRange(ports); if (ports.Length != 0) { this.TerminalPortCB.SelectedItem = ((Gurux.Terminal.GXTerminal)SelectedMedia).PortName; } this.TerminalPhoneNumberTB.Text = ((Gurux.Terminal.GXTerminal)SelectedMedia).PhoneNumber; } else { //Initialize terminal settings. Gurux.Terminal.GXTerminal termial = new Gurux.Terminal.GXTerminal(); string[] ports = GXTerminal.GetPortNames(); this.TerminalPortCB.Items.AddRange(ports); if (ports.Length != 0) { termial.PortName = ports[0]; } termial.BaudRate = 9600; termial.DataBits = 8; termial.Parity = Parity.None; termial.StopBits = StopBits.One; this.TerminalPhoneNumberTB.Text = termial.PhoneNumber; //termial.InitializeCommands = "AT+CBST=71,0,1\r\n"; this.MediasCB.Items.Add(termial); } //Select first media if medis is not selected. if (SelectedMedia == null) { SelectedMedia = (Gurux.Common.IGXMedia) this.MediasCB.Items[0]; } this.MediasCB.SelectedItem = SelectedMedia; if (!string.IsNullOrEmpty(Device.Password)) { this.PasswordTB.Text = ASCIIEncoding.ASCII.GetString(CryptHelper.Decrypt(Device.Password, Password.Key)); } if (dev != null) { this.UseLNCB.Checked = dev.UseLogicalNameReferencing; } this.AuthenticationCB.SelectedIndexChanged += new System.EventHandler(this.AuthenticationCB_SelectedIndexChanged); bool bConnected = Device.Media != null && Device.Media.IsOpen; SerialPortCB.Enabled = AdvancedBtn.Enabled = ManufacturerCB.Enabled = MediasCB.Enabled = AuthenticationCB.Enabled = UseRemoteSerialCB.Enabled = OKBtn.Enabled = !bConnected; HostNameTB.ReadOnly = PortTB.ReadOnly = PasswordTB.ReadOnly = WaitTimeTB.ReadOnly = PhysicalServerAddressTB.ReadOnly = NameTB.ReadOnly = bConnected; } catch (Exception Ex) { GXDLMS.Common.Error.ShowError(this, Ex); } }
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."); } }