/// <summary> /// Constructor. /// </summary> /// <param name="client">DLMS Client.</param> /// <param name="media">Media.</param> public GXDLMSReader(GXDLMSSecureClient client, IGXMedia media, TraceLevel trace, ILogger logger) { Trace = trace; Media = media; Client = client; _logger = logger; }
static public byte[] ReadReadout(IGXMedia media, string data, int wt) { ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>() { Eop = GetEops(), WaitTime = wt }; lock (media.Synchronous) { if (data != null) { media.Send(data, null); } do { if (!media.Receive(p)) { //There is no eop or CRC. break; } }while (p.Reply[p.Reply.Length - 1] != 0x3); //Read CRC if EOP is found. if (p.Reply[p.Reply.Length - 1] == 0x3) { p.Eop = null; p.Count = 1; if (!media.Receive(p)) { throw new Exception("Failed to receive reply from the device in given time."); } } } return(p.Reply); }
/// <summary> /// Constructor. /// </summary> /// <param name="client">DLMS Client.</param> /// <param name="media">Media.</param> /// <param name="trace">Trace level.</param> /// <param name="invocationCounter">Logical name of invocation counter.</param> /// <param name="iec">Is optical head used.</param> public GXDLMSReader(GXDLMSSecureClient client, IGXMedia media, TraceLevel trace, string invocationCounter) { Trace = trace; Media = media; Client = client; InvocationCounter = invocationCounter; }
/// <summary> /// Close connection to the meter. /// </summary> public void Close() { if (Media != null && Client != null) { try { if (Trace > TraceLevel.Info) { Console.WriteLine("Disconnecting from the meter."); } GXReplyData reply = new GXReplyData(); //Release is called only for secured connections. Some older meters don't support release and it might kill them. if (Client is GXDLMSSecureClient && (Client as GXDLMSSecureClient).Ciphering.Security != Security.None) { ReadDataBlock(Client.ReleaseRequest(), reply); } reply.Clear(); ReadDLMSPacket(Client.DisconnectRequest(), reply); Media.Close(); } catch { } Media = null; Client = null; } }
/// <summary> /// Constructor. /// </summary> /// <param name="client">DLMS Client.</param> /// <param name="media">Media.</param> /// <param name="trace">Trace settings.</param> /// <param name="useIec">Is serial port communication startted with IEC.</param> public GXDLMSReader(GXDLMSClient client, IGXMedia media, TraceLevel trace, bool useIec) { Trace = trace; Media = media; Client = client; UseIec = useIec; }
/// <summary> /// Constructor. /// </summary> /// <param name="client">DLMS Client.</param> /// <param name="media">Media.</param> public GXDLMSReader(GXDLMSSecureClient client, IGXMedia media, ILogger logger) { if (logger.IsEnabled(LogLevel.Trace) || logger.IsEnabled(LogLevel.Debug)) { Trace = TraceLevel.Verbose; } else if (logger.IsEnabled(LogLevel.Information)) { Trace = TraceLevel.Info; } else if (logger.IsEnabled(LogLevel.Warning)) { Trace = TraceLevel.Warning; } else if (logger.IsEnabled(LogLevel.Error) || logger.IsEnabled(LogLevel.Critical)) { Trace = TraceLevel.Error; } else { Trace = TraceLevel.Off; } Media = media; Client = client; _logger = logger; }
/// <summary> /// Close connection to the meter. /// </summary> public void Close() { if (Media != null && Client != null) { try { if (Trace > TraceLevel.Info) { Console.WriteLine("Disconnecting from the meter."); } GXReplyData reply = new GXReplyData(); try { ReadDataBlock(Client.ReleaseRequest(), reply); } catch (Exception) { //All meters don't support release. } reply.Clear(); ReadDLMSPacket(Client.DisconnectRequest(), reply); Media.Close(); } catch { } Media = null; Client = null; } }
/// <summary> /// Constructor. /// </summary> public GXCommunicatation(Gurux.DLMS.GXDLMS dlms, IGXMedia media, bool initializeIEC, Gurux.DLMS.Authentication authentication, string password) { m_Parser = dlms; Media = media; InitializeIEC = initializeIEC; m_Parser.Authentication = authentication; m_Parser.Password = password; }
/// <summary> /// Constructor. /// </summary> /// <param name="client">DLMS Client.</param> /// <param name="media">Media.</param> /// <param name="trace">Trace level.</param> /// <param name="invocationCounter">Logical name of invocation counter.</param> /// <param name="iec">Is optical head used.</param> public GXDLMSReader(GXDLMSSecureClient client, IGXMedia media, TraceLevel trace, string invocationCounter, bool useOpticalHead) { Trace = trace; Media = media; Client = client; InvocationCounter = invocationCounter; UseOpticalHead = useOpticalHead; }
public void Initialize(IGXMedia media, TraceLevel trace, string path, UInt32 sn) { serialNumber = sn; objectsFile = path; Media = media; Trace = trace; Init(); }
public void Initialize(IGXMedia media, TraceLevel trace, string path, UInt32 sn, bool exclusive) { serialNumber = sn; objectsFile = path; Media = media; Trace = trace; Exclusive = exclusive; Init(exclusive); }
/// <summary> /// Show settings of selected media. /// </summary> private void MediaCB_SelectedIndexChanged(object sender, EventArgs e) { try { MediaFrame.Controls.Clear(); GXClient cl = new GXClient(); SelectedMedia = cl.SelectMedia(MediaCB.Text); if (SelectedMedia == null) { throw new Exception(MediaCB.Text + " media not found."); } if (!string.IsNullOrEmpty(Gurux.DeviceSuite.Properties.Settings.Default.CommandPrompSettings)) { List<string> arr = new List<string>(Gurux.DeviceSuite.Properties.Settings.Default.CommandPrompSettings.Split(new char[]{';'})); if (arr.Count > 1) { arr.RemoveAt(0); SelectedMedia.Settings = string.Join(";", arr.ToArray()); } } if (SelectedMedia is GXSerial) { (SelectedMedia as GXSerial).AvailablePorts = DataCollector.SerialPorts; } if (SelectedMedia is GXAmiGateway) { GXAmiGateway gw = SelectedMedia as GXAmiGateway; gw.Host = Gurux.DeviceSuite.Properties.Settings.Default.AmiHostName; gw.UserName = Gurux.DeviceSuite.Properties.Settings.Default.AmiUserName; gw.Password = Gurux.DeviceSuite.Properties.Settings.Default.AmiPassword; } PropertiesForm = SelectedMedia.PropertiesForm; ((IGXPropertyPage)PropertiesForm).Initialize(); while (PropertiesForm.Controls.Count != 0) { Control ctr = PropertiesForm.Controls[0]; if (ctr is Panel) { if (!ctr.Enabled) { PropertiesForm.Controls.RemoveAt(0); continue; } } MediaFrame.Controls.Add(ctr); } } catch (Exception ex) { GXCommon.ShowError(this, ex); } }
/// <summary> /// Constructor. /// </summary> public GXCommunicatation(GXDLMSSecureClient 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"); } }
/// <summary> /// Media type is changed. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnMediaTypeChanged(object sender, EventArgs e) { try { if (media != null) { media.OnMediaStateChange -= OnMediaStateChange; media.OnReceived -= OnReceived; media.OnTrace -= MediaOnTrace; } bool isSerial = sender == SerialMnu || sender == SerialBtn; if (isSerial) { media = new GXSerial(); media.Settings = Settings.Default.HdlcAddressSerialSettings; media.OnMediaStateChange += OnMediaStateChange; media.OnReceived += OnReceived; media.OnTrace += MediaOnTrace; media.Trace = TraceLevel.Verbose; Settings.Default.HdlcAddressMedia = "GXSerial"; if (Settings.Default.HdlcAddressScanBaudRates) { (media as GXSerial).ConfigurableSettings = Gurux.Serial.AvailableMediaSettings.All & ~Gurux.Serial.AvailableMediaSettings.BaudRate; } else { (media as GXSerial).ConfigurableSettings = Gurux.Serial.AvailableMediaSettings.All; } } else { media = new GXNet(); (media as GXNet).ConfigurableSettings = Gurux.Net.AvailableMediaSettings.All & ~Gurux.Net.AvailableMediaSettings.Server; media.Settings = Settings.Default.HdlcAddressNetworkSettings; media.OnMediaStateChange += OnMediaStateChange; media.OnReceived += OnReceived; media.OnTrace += MediaOnTrace; media.Trace = TraceLevel.Verbose; Settings.Default.HdlcAddressMedia = "GXNet"; } UpdateStatus("Ready."); SerialBtn.Checked = UseOpticalProbeMnu.Enabled = SerialMnu.Checked = isSerial; NetworkBtn.Checked = NetworkMnu.Checked = !isSerial; ScanBaudRatesMnu.Enabled = ScanBaudRatesBtn.Enabled = OpticalProbeBtn.Enabled = UseOpticalProbeMnu.Enabled = isSerial; } catch (Exception ex) { MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
private void MediasCB_SelectedIndexChanged(object sender, EventArgs e) { try { SelectedMedia = (Gurux.Common.IGXMedia)MediasCB.SelectedItem; if (SelectedMedia is GXSerial || SelectedMedia is GXNet) { MediaPropertiesForm = null; CustomSettings.Visible = false; SerialSettingsGB.Visible = SelectedMedia is GXSerial; NetworkSettingsGB.Visible = SelectedMedia is GXNet; TerminalSettingsGB.Visible = false; if (SelectedMedia is GXNet && this.PortTB.Text == "") { this.PortTB.Text = "4059"; } } else { SerialSettingsGB.Visible = NetworkSettingsGB.Visible = TerminalSettingsGB.Visible = false; CustomSettings.Visible = true; CustomSettings.Controls.Clear(); MediaPropertiesForm = SelectedMedia.PropertiesForm; (MediaPropertiesForm as IGXPropertyPage).Initialize(); while (MediaPropertiesForm.Controls.Count != 0) { Control ctr = MediaPropertiesForm.Controls[0]; if (ctr is Panel) { if (!ctr.Enabled) { MediaPropertiesForm.Controls.RemoveAt(0); continue; } } CustomSettings.Controls.Add(ctr); ctr.Visible = true; } } UpdateStartProtocol(); } catch (Exception Ex) { MessageBox.Show(this, Ex.Message, Properties.Resources.CTT, MessageBoxButtons.OK, MessageBoxIcon.Error); } }
public void Close() { if (Media != null && m_Parser != null) { try { Console.WriteLine("Disconnecting from the meter."); ReadDLMSPacket(m_Parser.DisconnectRequest()); Media.Close(); } catch { } Media = null; m_Parser = 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; } }
/// <summary> /// Constructor. /// </summary> /// <param name="client">DLMS Client.</param> /// <param name="media">Media.</param> /// <param name="logger">Logger.</param> /// <param name="trace">Trace level.</param> public GXDLMSReader( GXDLMSSecureClient client, IGXMedia media, ILogger logger, TraceLevel trace, int wt, int retry, UInt64 deviceId) { WaitTime = wt * 1000; RetryCount = retry; Trace = trace; Media = media; Client = client; _logger = logger; DeviceId = deviceId; }
/// <summary> /// Media type is changed. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnMediaTypeChanged(object sender, EventArgs e) { try { if (media != null) { media.OnMediaStateChange -= OnMediaStateChange; media.OnReceived -= OnReceived; media.OnTrace -= MediaOnTrace; } bool isSerial = sender == SerialMnu || sender == SerialBtn; if (isSerial) { media = new GXSerial(); media.Settings = Settings.Default.PlcSerialSettings; media.OnMediaStateChange += OnMediaStateChange; media.OnReceived += OnReceived; media.OnTrace += MediaOnTrace; if (GXSerial.GetPortNames().Length == 0) { MediaSettingsMnu.Enabled = MediaSettingsMnu.Enabled = false; } Settings.Default.PlcMedia = "GXSerial"; } else { media = new GXNet(); (media as GXNet).ConfigurableSettings = Gurux.Net.AvailableMediaSettings.All & ~Gurux.Net.AvailableMediaSettings.Server; media.Settings = Settings.Default.PlcNetworkSettings; media.OnMediaStateChange += OnMediaStateChange; media.OnReceived += OnReceived; media.OnTrace += MediaOnTrace; MediaSettingsMnu.Enabled = MediaSettingsMnu.Enabled = true; Settings.Default.PlcMedia = "GXNet"; } media.Trace = TraceLevel.Verbose; UpdateStatus("Ready."); SerialBtn.Checked = SerialMnu.Checked = isSerial; NetworkBtn.Checked = NetworkMnu.Checked = !isSerial; } catch (Exception ex) { MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
public GXHdlcAddressesResolverDlg(IGXMedia media) { InitializeComponent(); if (Properties.Settings.Default.HdlcAddressScanBaudRates && (media is GXSerial s)) { List <string> list = new List <string>(Properties.Settings.Default.HdlcAddressBaudRates.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)); foreach (int rate in s.GetAvailableBaudRates(null)) { if (rate != 0) { bool c = list.Contains(rate.ToString()); BaudRatesCl.Items.Add(rate.ToString(), c); } } } else { BaudRatesPanel.Visible = false; } CustomSettings.Controls.Clear(); MediaPropertiesForm = media.PropertiesForm; (MediaPropertiesForm as IGXPropertyPage).Initialize(); while (MediaPropertiesForm.Controls.Count != 0) { Control ctr = MediaPropertiesForm.Controls[0]; if (ctr is Panel) { if (!ctr.Enabled) { MediaPropertiesForm.Controls.RemoveAt(0); continue; } } CustomSettings.Controls.Add(ctr); ctr.Visible = true; } TestFoundMetersFirstCb.Checked = Properties.Settings.Default.TestFoundMetersFirst; TestFailedClientsLastCb.Checked = Properties.Settings.Default.TestFailedClientsLast; ServerAddressesTb.Text = Properties.Settings.Default.HdlcServerAddresses.Replace(",", Environment.NewLine); ClientAddressesTb.Text = Properties.Settings.Default.HdlcClientAddresses.Replace(",", Environment.NewLine); InitializeWaitTimeTb.Text = Properties.Settings.Default.HdlcSearchInitialWaitTime.ToString(); SearchWaitTimeTb.Text = Properties.Settings.Default.HdlcSearchWaitTime.ToString(); ConnectionDelayTb.Text = Properties.Settings.Default.HdlcConnectionDelay.ToString(); }
/// <summary> /// Disconnect. /// </summary> public void Disconnect() { if (Media != null && Client != null) { try { if (Trace > TraceLevel.Info) { Console.WriteLine("Disconnecting from the meter."); } GXReplyData reply = new GXReplyData(); ReadDLMSPacket(Client.DisconnectRequest(), reply); Media.Close(); } catch { } Media = null; Client = null; } }
/// <summary> /// Close connection to the meter. /// </summary> public void Close() { if (Media != null && Client != null) { try { if (Trace > TraceLevel.Info) { Console.WriteLine("Disconnecting from the meter."); } GXReplyData reply = new GXReplyData(); try { if ((Client.ConnectionState & ConnectionState.Dlms) != 0 && (Client.InterfaceType == InterfaceType.WRAPPER || Client.Ciphering.Security != (byte)Security.None)) { ReadDataBlock(Client.ReleaseRequest(), reply); } } catch (Exception ex) { //All meters don't support Release. Console.WriteLine("Release failed. " + ex.Message); } reply.Clear(); if (Client.ConnectionState != 0) { ReadDLMSPacket(Client.DisconnectRequest(), reply); } Media.Close(); } catch { } Media = null; Client = null; } }
/// <summary> /// Disconnect. /// </summary> /// <param name="serial"></param> /// <param name="tryCount"></param> public static void Disconnect(IGXMedia media, int tryCount) { lock (media.Synchronous) { ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>() { Eop = GetEops(), WaitTime = 1000 }; List <byte> data = new List <byte>(); data.Add(0x01); data.Add((byte)'B'); data.Add((byte)'0'); data.Add(0x03); data.Add(CalculateChecksum(data, 1, data.Count - 1)); byte[] data1 = data.ToArray(); string header, frame; media.Send(data1, null); media.Receive(p); while (--tryCount > -1) { if (media.Receive(p)) { GetPacket(new List <byte>(p.Reply), false, out header, out frame); if (header == "B0") { break; } if (p.Reply.Length > 11) { p.Reply = null; } } media.Send(data1, null); } } }
/// <summary> /// Close connection to the meter. /// </summary> public void Close() { if (Media != null && Client != null) { try { if (Trace > TraceLevel.Info) { Console.WriteLine("Disconnecting from the meter."); } GXReplyData reply = new GXReplyData(); try { //Release is call only for secured connections. //All meters are not supporting Release and it's causing problems. if (Client.InterfaceType == InterfaceType.WRAPPER || (Client.InterfaceType == InterfaceType.HDLC && Client.Ciphering.Security != (byte)Security.None)) { ReadDataBlock(Client.ReleaseRequest(), reply); } } catch (Exception ex) { //All meters don't support Release. Console.WriteLine("Release failed. " + ex.Message); } reply.Clear(); ReadDLMSPacket(Client.DisconnectRequest(), reply); Media.Close(); } catch { } Media = null; Client = null; } }
static public byte[] Read(IGXMedia media, string data, char baudRate, int wt, bool useCrc) { return SendData(media, ASCIIEncoding.ASCII.GetBytes(data), baudRate, wt, useCrc, true, true); }
/// <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"); } } }
static byte[] SendData(IGXMedia media, byte[] data, char baudRate, int wt, bool useCrcSend, bool useCrcReply, bool readAllDataOnce) { ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>() { Eop = GetEops(), WaitTime = wt }; lock (media.Synchronous) { if (data != null) { media.Send(data, null); if (baudRate != '\0' && media.MediaType == "Serial") { Gurux.Serial.GXSerial serial = media as Gurux.Serial.GXSerial; while (serial.BytesToWrite != 0) { System.Threading.Thread.Sleep(100); } System.Threading.Thread.Sleep(200); switch (baudRate) { case '0': serial.BaudRate = 300; break; case '1': case 'A': serial.BaudRate = 600; break; case '2': case 'B': serial.BaudRate = 1200; break; case '3': case 'C': serial.BaudRate = 2400; break; case '4': case 'D': serial.BaudRate = 4800; break; case '5': case 'E': serial.BaudRate = 9600; break; case '6': case 'F': serial.BaudRate = 19200; break; default: throw new Exception("Unknown baud rate."); } } } if (!media.Receive(p)) { throw new Exception("Failed to receive reply from the device in given time."); } List <byte> reply2 = new List <byte>(); reply2.AddRange(p.Reply); p.Reply = null; string header, frame; byte[] packet = null; if (useCrcSend && data != null) { while ((packet = GetPacket(reply2, false, out header, out frame)) == null) { p.Eop = null; p.Count = 1; if (!media.Receive(p)) { throw new Exception("Failed to receive reply from the device in given time."); } reply2.AddRange(p.Reply); p.Reply = null; } p.Eop = GetEops(); } else { for (int pos = 0; pos != reply2.Count; ++pos) { if (reply2[pos] == 0xA) { ++pos; packet = new byte[pos]; reply2.CopyTo(0, packet, 0, pos); break; } } } //Remove echo. if (data != null && EqualBytes(data, packet)) { reply2.RemoveRange(0, data.Length); if (useCrcReply && reply2.Count != 0)// && !(data != null && data[data.Length - 1] == 0xA)) { while (GetPacket(reply2, false, out header, out frame) == null) { p.Eop = null; p.Count = 1; if (!media.Receive(p)) { throw new Exception("Failed to receive reply from the device in given time."); } reply2.AddRange(p.Reply); p.Reply = null; } } else { if (GetPacket(reply2, false, out header, out frame) == null) { reply2.AddRange(SendData(media, null, baudRate, wt, useCrcSend, useCrcReply, readAllDataOnce)); } } //If there is more data available. if (readAllDataOnce && reply2[reply2.Count - 2] == 0x4) { reply2.AddRange(SendData(media, new byte[] { 6 }, '\0', wt, useCrcSend, useCrcReply, readAllDataOnce)); } return(reply2.ToArray()); } if (useCrcReply && !(data != null && data[data.Length - 1] == 0xA)) { while (GetPacket(reply2, false, out header, out frame) == null) { p.Eop = null; p.Count = 1; if (!media.Receive(p)) { throw new Exception("Failed to receive reply from the device in given time."); } reply2.AddRange(p.Reply); p.Reply = null; } } return(reply2.ToArray()); } }
private void Connect(string serialNumber, string password, Protocol protocol, IGXMedia media, int waittime) { string data = "/?" + serialNumber + "!\r\n"; byte[] reply = IEC62056Parser.Identify(media, data, '\0', waittime); System.Diagnostics.Debug.WriteLine(ASCIIEncoding.ASCII.GetString(reply)); if (reply[0] != '/') { throw new Exception("Invalid reply."); } char baudRate = (char)reply[4]; string CModeBauds = "0123456789"; string BModeBauds = "ABCDEFGHI"; Protocol mode; if (CModeBauds.IndexOf(baudRate) != -1) { mode = Protocol.ModeC; } else if (BModeBauds.IndexOf(baudRate) != -1) { mode = Protocol.ModeB; } else { mode = Protocol.ModeA; baudRate = '0'; } if (reply[0] != '/') { throw new Exception("Import failed. Invalid reply."); } string manufacturer = new string(new char[] { (char)reply[1], (char)reply[2], (char)reply[3] }); if (protocol == Protocol.ModeA) { data = (char)0x06 + "0" + baudRate + "0\r\n"; } else { data = (char)0x06 + "0" + baudRate + "1\r\n"; } //Note this sleep is in standard. Do not remove. System.Threading.Thread.Sleep(300); reply = IEC62056Parser.ParseHandshake(media, data, baudRate, waittime); string header, frame; IEC62056Parser.GetPacket(new List<byte>(reply), true, out header, out frame); System.Diagnostics.Debug.WriteLine(frame); if (header == "B0") { throw new Exception("Connection failed. Meter do not accept connection at the moment."); } //Password is asked and it is given. if (header == "P0" && !string.IsNullOrEmpty(password)) { System.Diagnostics.Debug.WriteLine("Password is asked."); //If Elster A1700 if (manufacturer.Equals("GEC")) { password = ElsterEncrypt(password, frame); } data = (char)1 + "P2" + (char)2 + "(" + password + ")" + (char)3; List<byte> tmp = new List<byte>(ASCIIEncoding.ASCII.GetBytes(data)); data = data + (char) IEC62056Parser.CalculateChecksum(tmp, 1, -1); reply = IEC62056Parser.Read(media, data, baudRate, waittime, true); if (reply == null || (reply.Length != 1 && reply[0] != 6)) { throw new Exception("Connection failed. Invalid password."); } } }
public override void ImportFromDevice(Control[] addinPages, GXDevice device, IGXMedia media) { media.Open(); GXMBusDevice dev = device as GXMBusDevice; object data; //Handshake ShortFrame sf = new ShortFrame(); sf.AddressField = dev.DeviceAddress; sf.ControlField = (byte)CFieldFunctions.SendSlaveInit; sf.CountChecksum(); data = sf.ToByteArray(); ReceiveParameters<byte[]> recParams = new ReceiveParameters<byte[]>() { Count = 1, Peek = false, WaitTime = device.WaitTime }; lock (media.Synchronous) { media.Send(data, null); if (!media.Receive(recParams)) { throw new Exception("Failed to receive reply from the device in given time."); } if (recParams.Reply.Length < 1 || recParams.Reply[0] != 0xE5) { throw new Exception("Handshake failed."); } bool morePacketsAvailable = false; byte fcb = 1; List<MBusRegister> items = new List<MBusRegister>(); do { sf = new ShortFrame(); sf.AddressField = dev.DeviceAddress; if (fcb == 1) { sf.ControlField = (byte)CFieldFunctions.RequestClass2Data; } else { sf.ControlField = (byte)CFieldFunctions.RequestClass2Data | (byte)CFieldRequest.FrameCountBit; } sf.CountChecksum(); recParams.AllData = true; recParams.Count = 1; recParams.Eop = (byte)0x16; recParams.Reply = null; int cnt = 0; //Some meters can't answer right a way. do { media.Send(sf.ToByteArray(), null); if (++cnt == 6) { throw new Exception("Failed to receive reply from the device in given time."); } } while (!media.Receive(recParams)); while (!VerifyReadReplyCheckSum(recParams.Reply)) { recParams.Count = 0; recParams.Reply = null; bool gotData = media.Receive(recParams); if (!gotData) { break; } } morePacketsAvailable = recParams.Reply.Length > 5 && (recParams.Reply[4] & 0x10) != 0; items.AddRange(ParseReadReply(recParams.Reply)); } while (morePacketsAvailable); GXMBusCategory defaultCategory = null; if ((defaultCategory = (GXMBusCategory)device.Categories.Find("Default")) == null) { defaultCategory = new GXMBusCategory(); defaultCategory.Name = "Default"; device.Categories.Add(defaultCategory); } for (int pos = 0; pos < items.Count; ++pos) { MBusRegister item = items[pos]; GXMBusProperty prop = new GXMBusProperty(); prop.Ordinal = pos; if (item.IsVariableData) { string name = item.MBusType; int len = name.IndexOf('_'); if (len != -1) { name = name.Substring(0, len); } name += " " + item.Function.ToString(); if (item.Tariff != 0) { name += " Tariff " + item.Tariff.ToString(); } prop.Name = name; prop.Unit = item.Unit; prop.DataLength = item.DataLength; item.Mask.Reverse(); prop.InfoMask = item.Mask.ToArray(); prop.Type = item.Type; if (item.MBusType.ToLower().Contains("date") || item.MBusType.ToLower().Contains("timepoint")) { prop.ValueType = typeof(DateTime); } else { prop.ValueType = typeof(string); } } else { prop.Name = item.MBusType; prop.Unit = item.Unit; prop.ValueType = typeof(string); prop.DataLength = 4; } prop.InfoBytes = item.InformationBytes.Reverse().ToArray(); defaultCategory.Properties.Add(prop); } } }
static byte[] SendData(IGXMedia media, byte[] data, char baudRate, int wt, bool useCrcSend, bool useCrcReply, bool readAllDataOnce) { ReceiveParameters<byte[]> p = new ReceiveParameters<byte[]>() { Eop = GetEops(), WaitTime = wt }; lock (media.Synchronous) { if (data != null) { media.Send(data, null); if (baudRate != '\0' && media.MediaType == "Serial") { Gurux.Serial.GXSerial serial = media as Gurux.Serial.GXSerial; while (serial.BytesToWrite != 0) { System.Threading.Thread.Sleep(100); } System.Threading.Thread.Sleep(200); switch (baudRate) { case '0': serial.BaudRate = 300; break; case '1': case 'A': serial.BaudRate = 600; break; case '2': case 'B': serial.BaudRate = 1200; break; case '3': case 'C': serial.BaudRate = 2400; break; case '4': case 'D': serial.BaudRate = 4800; break; case '5': case 'E': serial.BaudRate = 9600; break; case '6': case 'F': serial.BaudRate = 19200; break; default: throw new Exception("Unknown baud rate."); } } } if (!media.Receive(p)) { throw new Exception("Failed to receive reply from the device in given time."); } List<byte> reply2 = new List<byte>(); reply2.AddRange(p.Reply); p.Reply = null; string header, frame; byte[] packet = null; if (useCrcSend && data != null) { while ((packet = GetPacket(reply2, false, out header, out frame)) == null) { p.Eop = null; p.Count = 1; if (!media.Receive(p)) { throw new Exception("Failed to receive reply from the device in given time."); } reply2.AddRange(p.Reply); p.Reply = null; } p.Eop = GetEops(); } else { for (int pos = 0; pos != reply2.Count; ++pos) { if (reply2[pos] == 0xA) { ++pos; packet = new byte[pos]; reply2.CopyTo(0, packet, 0, pos); break; } } } //Remove echo. if (data != null && EqualBytes(data, packet)) { reply2.RemoveRange(0, data.Length); if (useCrcReply && reply2.Count != 0)// && !(data != null && data[data.Length - 1] == 0xA)) { while (GetPacket(reply2, false, out header, out frame) == null) { p.Eop = null; p.Count = 1; if (!media.Receive(p)) { throw new Exception("Failed to receive reply from the device in given time."); } reply2.AddRange(p.Reply); p.Reply = null; } } else { if (GetPacket(reply2, false, out header, out frame) == null) { reply2.AddRange(SendData(media, null, baudRate, wt, useCrcSend, useCrcReply, readAllDataOnce)); } } //If there is more data available. if (readAllDataOnce && reply2[reply2.Count - 2] == 0x4) { reply2.AddRange(SendData(media, new byte[] { 6 }, '\0', wt, useCrcSend, useCrcReply, readAllDataOnce)); } return reply2.ToArray(); } if (useCrcReply && !(data != null && data[data.Length - 1] == 0xA)) { while (GetPacket(reply2, false, out header, out frame) == null) { p.Eop = null; p.Count = 1; if (!media.Receive(p)) { throw new Exception("Failed to receive reply from the device in given time."); } reply2.AddRange(p.Reply); p.Reply = null; } } return reply2.ToArray(); } }
/// <summary> /// Constructor. /// </summary> /// <param name="client">DLMS Client.</param> /// <param name="media">Media.</param> /// <param name="trace">Trace level.</param> public GXDLMSReader(GXDLMSClient client, IGXMedia media, TraceLevel trace) { Trace = trace; Media = media; Client = client; }
static void Main(string[] args) { IGXMedia media = null; GXCommunicatation comm = null; try { //////////////////////////////////////// //Handle command line parameters. String id = "", host = "", port = "", pw = ""; bool trace = false, iec = true, isSerial = false; Authentication auth = Authentication.High; 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=", ""); isSerial = true; 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) || (!isSerial && string.IsNullOrEmpty(host))) //{ // ShowHelp(); // return; //} //////////////////////////////////////// //Initialize connection settings. if (isSerial) { GXSerial serial = media as GXSerial; string[] t = GXSerial.GetPortNames(); 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 { Gurux.Net.GXNet net = media as Gurux.Net.GXNet; net.Port = Convert.ToInt32(port); net.HostName = host; net.Protocol = Gurux.Net.NetworkType.Tcp; } //////////////////////////////////////// //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); } Gurux.DLMS.GXDLMS dlms = new Gurux.DLMS.GXDLMS(); //Update Obis code list so we can get right descriptions to the objects. dlms.ObisCodes = man.ObisCodes; comm = new GXCommunicatation(dlms, media, iec, auth, pw); comm.Trace = trace; comm.InitializeConnection(man); //Save Association view to the cache so it is not needed to retreave every time. string path = man.Identification + ".xml"; Gurux.DLMS.GXDLMSObjectCollection objects = null; Type[] extraTypes = new Type[] { typeof(GXManufacturerCollection), typeof(GXManufacturer), typeof(GXObisCodeCollection), typeof(GXObisCode), typeof(GXObisValueItem), typeof(GXObisValueItemCollection), typeof(GXDLMSProfileGenericObject) }; XmlSerializer x = new XmlSerializer(typeof(GXDLMSObjectCollection), extraTypes); 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 Gurux.DLMS.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(); 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 (Gurux.DLMS.GXDLMSObject it in objects) { Console.WriteLine(it.Name + " " + it.Description); } } //Read available clock and data objects. foreach (Gurux.DLMS.GXDLMSObject it in objects.GetObjects(new ObjectType[] { ObjectType.Clock, ObjectType.Data })) { object value = comm.Read(it, 2); Console.WriteLine(it.Name + " " + it.Description + " " + value); } //Read Profile Generic columns. GXDLMSObjectCollection cols = null; foreach (Gurux.DLMS.GXDLMSObject it in objects.GetObjects(ObjectType.ProfileGeneric)) { Console.WriteLine("Profile Generic " + it.Name + " Columns:"); cols = comm.GetColumns(it); foreach (GXDLMSObject col in cols) { Console.Write(col.Name + " | "); } Console.WriteLine(""); //Read first row from Profile Generic. Console.WriteLine("Profile Generic " + it.Name + " Columns:"); object[] rows = comm.ReadRowsByEntry(it, 0, 1, cols); foreach (object[] row in rows) { foreach (object cell in row) { Console.Write(cell + " | "); } Console.WriteLine(""); } //Read last dayfrom Profile Generic. Console.WriteLine("Profile Generic " + it.Name + " Columns:"); rows = comm.ReadRowsByRange(it, DateTime.Now.Date, DateTime.MaxValue, cols); foreach (object[] row in rows) { foreach (object cell in row) { Console.Write(cell + " | "); } Console.WriteLine(""); } } } catch (Exception ex) { if (comm != null) { comm.Close(); } Console.WriteLine(ex.Message); if (!System.Diagnostics.Debugger.IsAttached) { Console.ReadKey(); } } finally { comm.Close(); if (System.Diagnostics.Debugger.IsAttached) { Console.ReadKey(); } } }
static public byte[] ReadReadout(IGXMedia media, string data, int wt) { ReceiveParameters<byte[]> p = new ReceiveParameters<byte[]>() { Eop = GetEops(), WaitTime = wt }; lock (media.Synchronous) { if (data != null) { media.Send(data, null); } do { if (!media.Receive(p)) { //There is no eop or CRC. break; } } while (p.Reply[p.Reply.Length - 1] != 0x3); //Read CRC if EOP is found. if (p.Reply[p.Reply.Length - 1] == 0x3) { p.Eop = null; p.Count = 1; if (!media.Receive(p)) { throw new Exception("Failed to receive reply from the device in given time."); } } } return p.Reply; }
/// <summary> /// Disconnect. /// </summary> /// <param name="serial"></param> /// <param name="tryCount"></param> public static void Disconnect(IGXMedia media, int tryCount) { lock (media.Synchronous) { ReceiveParameters<byte[]> p = new ReceiveParameters<byte[]>() { Eop = GetEops(), WaitTime = 1000 }; List<byte> data = new List<byte>(); data.Add(0x01); data.Add((byte)'B'); data.Add((byte)'0'); data.Add(0x03); data.Add(CalculateChecksum(data, 1, data.Count - 1)); byte[] data1 = data.ToArray(); string header, frame; media.Send(data1, null); media.Receive(p); while (--tryCount > -1) { if (media.Receive(p)) { GetPacket(new List<byte>(p.Reply), false, out header, out frame); if (header == "B0") { break; } if (p.Reply.Length > 11) { p.Reply = null; } } media.Send(data1, null); } } }
static public byte[] ParseHandshake(IGXMedia media, string data, char baudRate, int wt) { return SendData(media, ASCIIEncoding.ASCII.GetBytes(data), baudRate, wt, false, true, true); }
internal static void Read(ILogger _logger, System.Net.Http.HttpClient client, GXDLMSReader reader, GXTask task, IGXMedia net, GXDLMSObject obj) { AddValue v; System.Net.Http.HttpResponseMessage response; if (_logger != null) { _logger.LogInformation("Reading: " + obj.ToString()); } Console.WriteLine("Reading: " + obj.ToString()); object val; if (obj.ObjectType == ObjectType.ProfileGeneric && task.Index == 2 && GetReadTime(task.Object) != DateTime.MinValue && IsSortedByDateTime(task.Object)) { //Read profile generic using range. DateTime now = DateTime.Now; now = now.AddSeconds(-now.Second); now = now.AddMinutes(-now.Minute); now = now.AddHours(1); val = reader.ReadRowsByRange((GXDLMSProfileGeneric)obj, task.Object.Attributes[GetBufferIndex(task.Object)].Read, now); } else { val = reader.Read(obj, task.Index); } if (val is Enum) { //Enum values are saved as interger. val = Convert.ToString(Convert.ToInt32(val)); } else if (val is byte[]) { DataType dt = (DataType)task.Object.Attributes[GetBufferIndex(task.Object)].UIDataType; if (dt == DataType.String) { val = ASCIIEncoding.ASCII.GetString((byte[])val); } else if (dt == DataType.StringUTF8) { val = ASCIIEncoding.UTF8.GetString((byte[])val); } else { val = GXCommon.ToHex((byte[])val); } } else if (val is GXDateTime) { val = ((GXDateTime)val).ToFormatString(); } if (obj.ObjectType == ObjectType.ProfileGeneric && task.Index == 2) { //Make own value from each row. if (val != null) { UInt64 attributeId = task.Object.Attributes[GetBufferIndex(task.Object)].Id; List<GXValue> list = new List<GXValue>(); DateTime latest = task.Object.Attributes[GetBufferIndex(task.Object)].Read; DateTime first = latest; Boolean read = false; int period = -1; foreach (GXStructure row in (GXArray)val) { DateTime dt = DateTime.MinValue; task.Data = GXDLMSTranslator.ValueToXml(row); for (int pos = 0; pos != row.Count; ++pos) { if (row[pos] is byte[]) { row[pos] = GXDLMSClient.ChangeType((byte[])row[pos], DataType.DateTime); if (pos == 0) { dt = ((GXDateTime)row[pos]).Value.LocalDateTime; //If we have already read this row. if (dt <= first) { read = true; break; } if (dt > latest) { latest = dt; } } } //Some meters are returning null as date time to save bytes... if (pos == 0 && row[pos] == null) { if (period == -1) { period = GetCapturePeriod(task.Object); if (period == -1) { throw new Exception("Invalid capture period."); } } row[pos] = latest.AddMinutes(period); } } if (_logger != null) { _logger.LogInformation("Read: " + task.Data); } if (!read) { list.Add(new GXValue() { Read = dt, Value = task.Data, AttributeId = attributeId }); } } if (list.Count != 0) { v = new AddValue() { Items = list.ToArray() }; response = client.PostAsJsonAsync(Startup.ServerAddress + "/api/value/AddValue", v).Result; Helpers.CheckStatus(response); ListDevicesResponse r = response.Content.ReadAsAsync<ListDevicesResponse>().Result; } } } else { if (!(val is string)) { val = Convert.ToString(val); } task.Data = (string)val; if (_logger != null) { _logger.LogInformation("Read: " + (string)val); } int index = GetAttributeIndex(task.Object, task.Index); if (index != -1) { UInt64 attributeId = task.Object.Attributes[index].Id; v = new AddValue() { Items = new GXValue[] {new GXValue(){ AttributeId = attributeId, Read = DateTime.Now, Value = (string)val} } }; response = client.PostAsJsonAsync(Startup.ServerAddress + "/api/value/AddValue", v).Result; Helpers.CheckStatus(response); AddValueResponse r = response.Content.ReadAsAsync<AddValueResponse>().Result; } else { if (_logger != null) { _logger.LogInformation("Invalid task index: " + task.Index); } } } }
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(); } } }
static public byte[] Read(IGXMedia media, string data, char baudRate, int wt, bool useCrc) { return(SendData(media, ASCIIEncoding.ASCII.GetBytes(data), baudRate, wt, useCrc, true, true)); }
private void Connect(string serialNumber, string password, Protocol protocol, IGXMedia media, int waittime) { string data = "/?" + serialNumber + "!\r\n"; byte[] reply = IEC62056Parser.Identify(media, data, '\0', waittime); System.Diagnostics.Debug.WriteLine(ASCIIEncoding.ASCII.GetString(reply)); if (reply[0] != '/') { throw new Exception("Invalid reply."); } char baudRate = (char)reply[4]; string CModeBauds = "0123456789"; string BModeBauds = "ABCDEFGHI"; Protocol mode; if (CModeBauds.IndexOf(baudRate) != -1) { mode = Protocol.ModeC; } else if (BModeBauds.IndexOf(baudRate) != -1) { mode = Protocol.ModeB; } else { mode = Protocol.ModeA; baudRate = '0'; } if (reply[0] != '/') { throw new Exception("Import failed. Invalid reply."); } string manufacturer = new string(new char[] { (char)reply[1], (char)reply[2], (char)reply[3] }); if (protocol == Protocol.ModeA) { data = (char)0x06 + "0" + baudRate + "0\r\n"; } else { data = (char)0x06 + "0" + baudRate + "1\r\n"; } //Note this sleep is in standard. Do not remove. System.Threading.Thread.Sleep(300); reply = IEC62056Parser.ParseHandshake(media, data, baudRate, waittime); string header, frame; IEC62056Parser.GetPacket(new List <byte>(reply), true, out header, out frame); System.Diagnostics.Debug.WriteLine(frame); if (header == "B0") { throw new Exception("Connection failed. Meter do not accept connection at the moment."); } //Password is asked and it is given. if (header == "P0" && !string.IsNullOrEmpty(password)) { System.Diagnostics.Debug.WriteLine("Password is asked."); //If Elster A1700 if (manufacturer.Equals("GEC")) { password = ElsterEncrypt(password, frame); } data = (char)1 + "P2" + (char)2 + "(" + password + ")" + (char)3; List <byte> tmp = new List <byte>(ASCIIEncoding.ASCII.GetBytes(data)); data = data + (char)IEC62056Parser.CalculateChecksum(tmp, 1, -1); reply = IEC62056Parser.Read(media, data, baudRate, waittime, true); if (reply == null || (reply.Length != 1 && reply[0] != 6)) { throw new Exception("Connection failed. Invalid password."); } } }