// Write %IW1530 public static void TestWriteLoop() { IPEndPoint ep = new IPEndPoint(IPAddress.Parse("172.20.54.58"), 0xAF12); EnIPRemoteDevice WagoPlc = new EnIPRemoteDevice(ep); // class 166, instance 1, attribut 1 EnIPClass Class166 = new EnIPClass(WagoPlc, 166); EnIPInstance Instance1 = new EnIPInstance(Class166, 1); EnIPAttribut FirstMemoryByte = new EnIPAttribut(Instance1, 1); // Connect made & retry automatically WagoPlc.autoConnect = true; WagoPlc.autoRegisterSession = true; ushort i = 0; for (; ;) { FirstMemoryByte.RawData = BitConverter.GetBytes(i++); if (FirstMemoryByte.WriteDataToNetwork() == EnIPNetworkStatus.OnLine) { Console.WriteLine("OK"); } Thread.Sleep(200); } }
private EnIPRemoteDevice getDevice() { EnIPRemoteDevice remotedevice; IPAddress ip; if (cb_device.SelectedIndex == -1) { try { ip = IPAddress.Parse(cb_device.Text); } catch { // no valid ip: cb_device.Text = "192.168.1.1"; ip = IPAddress.Parse(cb_device.Text); } foreach (EnIPRemoteDevice rd in _selfCreatedRemoteDevicesOverIp) // connection to the adapter already opended somewhere here? { if (rd.IPAdd().Equals(ip)) { return(rd); } } remotedevice = new EnIPRemoteDevice(new System.Net.IPEndPoint(ip, 0xAF12), Properties.Settings.Default.TCP_LAN_Timeout); // create new one _selfCreatedRemoteDevicesOverIp.Add(remotedevice); } else { remotedevice = ((ComboboxItem)cb_device.SelectedItem).RemoteDevice; } return(remotedevice); }
// Read the first analog value on a Wago PLC 750-8xx public static void TestReadLoop() { IPEndPoint ep = new IPEndPoint(IPAddress.Parse("172.20.54.58"), 0xAF12); EnIPRemoteDevice WagoPlc = new EnIPRemoteDevice(ep); // class 103, instance 1, attribut 1 // could be class 4, Instance 104 (with status) or 107 (wihout), attribut 3 for all Input data EnIPClass Class103 = new EnIPClass(WagoPlc, 103); EnIPInstance Instance1 = new EnIPInstance(Class103, 1); EnIPAttribut FirstAnalogInput = new EnIPAttribut(Instance1, 1); WagoPlc.autoConnect = false; WagoPlc.autoRegisterSession = true; for (; ;) { // Connect or try re-connect, could be made with a long delay if (!WagoPlc.IsConnected()) { WagoPlc.Connect(); } if (!WagoPlc.IsConnected()) { return; } // all data will be put in the byte[] RawData member of EnIPInstanceAttribut if (FirstAnalogInput.ReadDataFromNetwork() == EnIPNetworkStatus.OnLine) { Console.WriteLine((FirstAnalogInput.RawData[1] << 8) | FirstAnalogInput.RawData[0]); } Thread.Sleep(200); } }
public ImplicitMessaging(TreeView devicetreeView) { InitializeComponent(); ClassView.ImageList = devicetreeView.ImageList; TreeNode baseNode = devicetreeView.SelectedNode; while (baseNode.Parent != null) { baseNode = baseNode.Parent; } device = (EnIPRemoteDevice)baseNode.Tag; foreach (TreeNode t in baseNode.Nodes) { ClassView.Nodes.Add((TreeNode)t.Clone()); } ClassView.ExpandAll(); ClassView.ItemDrag += new ItemDragEventHandler(ClassView_ItemDrag); this.Text = "Implicit Messaging with " + baseNode.Text; try { IPEndPoint LocalEp = new IPEndPoint(IPAddress.Parse(Properties.Settings.Default.DefaultIPInterface), 0x8AE); // It's not a problem to do this with more than one remote device, // the underlying udp socket is static device.Class1Activate(LocalEp); } catch { } }
static void client_DeviceArrival(EnIPRemoteDevice device) { Console.WriteLine("Arrvial of : " + device.IPAdd().ToString() + " - " + device.ProductName); // Query the object list : Assembly object, instance 1, atribut 1 Console.WriteLine("Classes inside :"); device.GetObjectList(); foreach (EnIPClass cl in device.SupportedClassLists) { Console.WriteLine("\t" + ((CIPObjectLibrary)cl.Id).ToString()); } // Close pending connection device.Dispose(); }
// Menu Item private TreeNode AddRemoteDevice(EnIPRemoteDevice remotedevice) { foreach (TreeNode tn in devicesTreeView.Nodes) { if ((tn.Tag as EnIPRemoteDevice).Equals(remotedevice)) { return(tn); } } TreeNode tn2 = new TreeNode(remotedevice.IPAdd().ToString() + " - " + remotedevice.ProductName, 1, 1); tn2.Tag = remotedevice; devicesTreeView.Nodes.Add(tn2); return(tn2); }
// Read 4.104.3 on an Eurotherm Epack public static void TestReadLoop() { IPEndPoint ep = new IPEndPoint(IPAddress.Parse("172.20.54.119"), 0xAF12); EnIPRemoteDevice EPack = new EnIPRemoteDevice(ep); // class 4, Instance 100, attribut 3 for all Input data EnIPClass Class4 = new EnIPClass(EPack, 4); // here we gives the decoder class (subclass of CIPObject) in the 3rd parameter EnIPInstance Instance100 = new EnIPInstance(Class4, 100, typeof(InstanceDecoder)); EnIPAttribut AllInputs = new EnIPAttribut(Instance100, 3); EPack.autoConnect = false; EPack.autoRegisterSession = true; for (; ;) { // Connect or try re-connect, could be made with a long delay if (!EPack.IsConnected()) { EPack.Connect(); } if (!EPack.IsConnected()) { return; } // all data will be put in the byte[] RawData member of EnIPInstanceAttribut // ... but decoded in the DecoderMemeber if (AllInputs.ReadDataFromNetwork() == EnIPNetworkStatus.OnLine) { // rawdata basic technic // Console.WriteLine((AllInputs.RawData[1] << 8) | AllInputs.RawData[0]); InstanceDecoder decoded = (InstanceDecoder)AllInputs.DecodedMembers; Console.WriteLine(decoded.AnalogInput); Console.WriteLine(decoded.Frequency / 10.0); // and so on } Thread.Sleep(200); // If a Forward Open is done such as in Class1Sample application sample, // the decoder is always called : a first ReadDataFromNetwork is mandatory // before that. } }
static void Main(string[] args) { Console.WriteLine("Starting"); IPEndPoint ep = new IPEndPoint(IPAddress.Parse("172.20.54.58"), 0xAF12); EnIPRemoteDevice WagoPlc = new EnIPRemoteDevice(ep); WagoPlc.autoConnect = true; WagoPlc.autoRegisterSession = true; // class 4, instance 107, attribut 3 : Input Data EnIPClass Class4 = new EnIPClass(WagoPlc, 4); EnIPInstance Instance107 = new EnIPInstance(Class4, 107); EnIPAttribut Inputs = new EnIPAttribut(Instance107, 3); // Read require, it provides the data size in the RawData field // If not, one have to make a new on it with the good size before // calling ForwardOpen : Inputs.RawData=new byte[xx] Inputs.ReadDataFromNetwork(); // Open an Udp endpoint, server mode is mandatory : default port 0x8AE // Local IP should be given if more than 1 ethernet/wifi interface is present IPEndPoint LocalEp = new IPEndPoint(IPAddress.Parse(""), 0x8AE); // It's not a problem to do this with more than one remote device, // the underlying udp socket is static WagoPlc.Class1Activate(LocalEp); // Not required in P2P mode WagoPlc.Class1AddMulticast("239.192.72.32"); // Attach concerned attributs to the UDP callback handler : here just one Inputs.Class1Enrolment(); // Register me to get notified Inputs.T2OEvent += new T2OEventHandler(Inputs_T2OEvent); // ForwardOpen in Multicast, T2O, cycle 200 ms, duration infinite (-1) Inputs.ForwardOpen(false, true, false, 200, -1); Console.WriteLine("Running, hit a key to stop"); Console.ReadKey(); Inputs.ForwardClose(); }
// Menu Item // Delete a Device, a class, an instance, an attribut private void deleteToolStripMenuItem_Click(object sender, EventArgs e) { TreeNode tn = devicesTreeView.SelectedNode; if (tn == null) { return; } DialogResult deleteOK = DialogResult.OK; if (tn.Tag is EnIPRemoteDevice) { // confirm if (Properties.Settings.Default.ConfirmDeleteDevice) { deleteOK = MessageBox.Show("Delete this device", tn.Text, MessageBoxButtons.OKCancel, MessageBoxIcon.Question); } if (deleteOK == DialogResult.OK) { EnIPRemoteDevice device = (tn.Tag as EnIPRemoteDevice); device.Disconnect(); // close the tcp connection devicesTreeView.Nodes.Remove(tn); // remove from the tree } } else { // confirm if (Properties.Settings.Default.ConfirmDeleteOthers) { deleteOK = MessageBox.Show("Delete", tn.Text, MessageBoxButtons.OKCancel, MessageBoxIcon.Question); } if (deleteOK == DialogResult.OK) { devicesTreeView.Nodes.Remove(tn); // only remove from the list } } }
// Each time we received a response to udp broadcast or udp/tcp unicast ListIdentity void On_DeviceArrival(EnIPRemoteDevice device) { if (InvokeRequired) { Invoke(new DeviceArrivalHandler(On_DeviceArrival), new object[] { device }); return; } // Device already present ? foreach (TreeNode tn in devicesTreeView.Nodes) { EnIPRemoteDevice oldRemoteDevice = (EnIPRemoteDevice)tn.Tag; if (oldRemoteDevice.Equals(device)) { oldRemoteDevice.CopyData(device); // change the icon if needed if (tn.SelectedImageIndex != 0) { tn.ImageIndex = tn.SelectedImageIndex = 0; } // change the Text maybe tn.Text = device.IPAdd().ToString() + " - " + device.ProductName; if (devicesTreeView.SelectedNode == tn) { devicesTreeView.SelectedNode = null; } return; } } TreeNode tn2 = new TreeNode(device.IPAdd().ToString() + " - " + device.ProductName, 0, 0); tn2.Tag = device; devicesTreeView.Nodes.Add(tn2); // Queue connection ThreadPool.QueueUserWorkItem((o) => device.Connect()); }
// Menu Item private void saveConfigurationAsToolStripMenuItem_Click(object sender, EventArgs e) { try { SaveFileDialog dlg = new SaveFileDialog(); dlg.FileName = Properties.Settings.Default.DefaultTreeFile; dlg.Filter = "csv|*.csv"; if (dlg.ShowDialog(this) != System.Windows.Forms.DialogResult.OK) { return; } string filename = dlg.FileName; Properties.Settings.Default.DefaultTreeFile = filename; StreamWriter sw = new StreamWriter(filename); char s = Properties.Settings.Default.CSVSeparator; sw.WriteLine("Device IP" + s + "Name" + s + "Class" + s + "ClassName" + s + "Instance" + s + "InstanceName" + s + "Attribute" + s + "AttributeName"); sw.WriteLine("// EnIPExplorer Device Tree, can be modified with a spreadsheet"); foreach (TreeNode tn in devicesTreeView.Nodes) { EnIPRemoteDevice remote = (EnIPRemoteDevice)tn.Tag; sw.WriteLine(remote.IPAdd().ToString() + s + remote.ProductName); SaveFileEnIPOject(sw, s.ToString() + s.ToString(), tn.Nodes); } sw.Close(); MessageBox.Show("Done", "File Save", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch { MessageBox.Show("File Error", "EnIPExplorer", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
// Menu Item // Add a new device not discovery using the broadcast technic : outside the local net private void addRemoteDeviceToolStripMenuItem_Click(object sender, EventArgs e) { if (client == null) { return; } var Input = new GenericInputBoxExtended <TextBox>("Remote device", "IP address", (o) => { o.Text = Properties.Settings.Default.DefaultRemoteDevice; }); DialogResult res = Input.ShowDialog(); if (res != DialogResult.OK) { return; } try { EnIPRemoteDevice remotedevice = new EnIPRemoteDevice(new System.Net.IPEndPoint(IPAddress.Parse(Input.genericInput.Text), 0xAF12), Properties.Settings.Default.TCP_WAN_TimeOut); remotedevice.ProductName = "EnIPExplorer temporary ProductName"; AddRemoteDevice(remotedevice); remotedevice.DeviceArrival += new DeviceArrivalHandler(On_DeviceArrival); remotedevice.DiscoverServer(); Properties.Settings.Default.DefaultRemoteDevice = Input.genericInput.Text; } catch { Trace.WriteLine("Error with IP : " + Input.genericInput.Text); } }
private void devicesTreeView_AfterSelect(object sender, TreeViewEventArgs e) { if (client == null) { return; } EnIPNetworkStatus ReadRet = EnIPNetworkStatus.OnLine; Cursor Memcurs = this.Cursor; this.Cursor = Cursors.WaitCursor; // It's a Device : top level if (e.Node.Tag is EnIPRemoteDevice) { EnIPRemoteDevice device = (EnIPRemoteDevice)e.Node.Tag; propertyGrid.SelectedObject = device; popupAddCToolStripMenuItem.Visible = true; popupAddIToolStripMenuItem.Visible = false; popupAddAToolStripMenuItem.Visible = false; decodeAttributAsToolStripMenuItem.Visible = false; popupDeleteToolStripMenuItem.Text = deleteToolStripMenuItem.Text = "Delete current Device"; if (device.SupportedClassLists.Count == 0) // certainly never discovers { if (device.IsConnected() == false) { device.Connect(); if (device.IsConnected() == false) { propertyGrid.Enabled = false; CurrentRemoteDeviceIcon(EnIPNetworkStatus.OffLine); this.Cursor = Memcurs; return; } } // never discovers if (device.DataLength == 0) { device.DiscoverServer(); } device.GetObjectList(); propertyGrid.Enabled = true; } // change the Text maybe String txt = device.IPAdd().ToString() + " - " + device.ProductName; if (e.Node.Text != txt) { e.Node.Text = txt; } foreach (EnIPClass clId in device.SupportedClassLists) { bool alreadyexist = false; foreach (TreeNode tn in e.Node.Nodes) { if ((tn.Tag as EnIPClass).Id == clId.Id) { alreadyexist = true; break; } } if (!alreadyexist) { e.Node.Nodes.Add(ClassToTreeNode(clId)); } } e.Node.Expand(); } // It's a Class else if (e.Node.Tag is EnIPClass) { // Read it from the remote devie EnIPClass EnClass = (EnIPClass)e.Node.Tag; ReadRet = EnClass.ReadDataFromNetwork(); LastReadNetworkStatus = EnIPNetworkStatus.OffLine; // to avoid periodic reading // In the Grid propertyGrid.SelectedObject = EnClass; propertyGrid.ExpandAllGridItems(); // Popup menu adaptation popupAddCToolStripMenuItem.Visible = true; popupAddIToolStripMenuItem.Visible = true; popupAddAToolStripMenuItem.Visible = false; decodeAttributAsToolStripMenuItem.Visible = false; popupDeleteToolStripMenuItem.Text = deleteToolStripMenuItem.Text = "Delete current Class"; } // It's an Instance else if (e.Node.Tag is EnIPInstance) { // Read it from the remote devie EnIPInstance Instance = (EnIPInstance)e.Node.Tag; LastReadNetworkStatus = ReadRet = Instance.ReadDataFromNetwork(); // remove properties litse filter based on CIPAttribut // in order to show all atrbiuts in the property grid if (Instance.DecodedMembers != null) { Instance.DecodedMembers.FilterAttribut(-1); } LastReadNetworkStatus = ReadRet = Instance.ReadDataFromNetwork(); // In the Grid propertyGrid.SelectedObject = Instance; propertyGrid.ExpandAllGridItems(); // Popup menu adaptation popupAddCToolStripMenuItem.Visible = true; popupAddIToolStripMenuItem.Visible = true; popupAddAToolStripMenuItem.Visible = true; decodeAttributAsToolStripMenuItem.Visible = false; popupDeleteToolStripMenuItem.Text = deleteToolStripMenuItem.Text = "Delete current Instance"; } // It's an Attribut else if (e.Node.Tag is EnIPAttribut) { // Read it from the remote devie EnIPAttribut Att = (EnIPAttribut)e.Node.Tag; LastReadNetworkStatus = ReadRet = Att.ReadDataFromNetwork(); // filter properties list for only the given attribut // remove instance undecoded bytes if exist if (Att.DecodedMembers != null) { Att.DecodedMembers.FilterAttribut(Att.Id); Att.DecodedMembers.Remain_Undecoded_Bytes = null; } // In the Grid propertyGrid.SelectedObject = Att; propertyGrid.ExpandAllGridItems(); // Popup menu adaptation popupAddCToolStripMenuItem.Visible = true; popupAddIToolStripMenuItem.Visible = true; popupAddAToolStripMenuItem.Visible = true; decodeAttributAsToolStripMenuItem.Visible = true; popupDeleteToolStripMenuItem.Text = deleteToolStripMenuItem.Text = "Delete current Attribute"; } propertyGrid.Enabled = (ReadRet == EnIPNetworkStatus.OnLine); CurrentRemoteDeviceIcon(ReadRet); this.Cursor = Memcurs; }
// Usage by Load file menu private void AddNodesFromFile(StreamReader sr, ref int line) { TreeNode ParentDeviceTreeNode = null, ParentClassTreeNode = null, ParentInstanceTreeNode = null; EnIPRemoteDevice remotedevice = null; EnIPClass Class = null; EnIPInstance Instance = null; while (!sr.EndOfStream) { try { String str = sr.ReadLine(); line++; if ((str != null) && (str[0] != '/')) { String[] Strs = str.Split(Properties.Settings.Default.CSVSeparator); int Length = Strs.Length; while (Length != 1) { if (Strs[Length - 1] == "") { Length--; } else { break; } } switch (Length) { case 2: // A device, assume LAN timeout and not WAN remotedevice = new EnIPRemoteDevice(new System.Net.IPEndPoint(IPAddress.Parse(Strs[0]), 0xAF12), Properties.Settings.Default.TCP_LAN_Timeout); remotedevice.ProductName = Strs[1]; ParentDeviceTreeNode = AddRemoteDevice(remotedevice); break; case 4: // A class Class = new EnIPClass(remotedevice, Convert.ToUInt16(Strs[2])); int ico; if (Enum.IsDefined(typeof(CIPObjectLibrary), Class.Id)) { ico = Classe2Ico((CIPObjectLibrary)Class.Id); } else { ico = 2; } ParentClassTreeNode = AddeNode(ParentDeviceTreeNode, Class, Strs[3], ico); ParentClassTreeNode.ToolTipText = "Node " + IdStr(Class.Id); break; case 6: // An instance Instance = new EnIPInstance(Class, Convert.ToByte(Strs[4])); ParentInstanceTreeNode = AddeNode(ParentClassTreeNode, Instance, Strs[5], 9); ParentInstanceTreeNode.ToolTipText = ParentClassTreeNode.ToolTipText + "." + IdStr(Instance.Id); break; case 8: // An attribut EnIPAttribut Attribut = new EnIPAttribut(Instance, Convert.ToByte(Strs[6])); TreeNode tnAtt = AddeNode(ParentInstanceTreeNode, Attribut, Strs[7], 10); tnAtt.ToolTipText = ParentInstanceTreeNode.ToolTipText + "." + IdStr(Attribut.Id); break; default: throw new Exception("Not the good number of colums"); } } } catch { throw new Exception("Line content error"); } } }
public ComboboxItem(EnIPRemoteDevice rd) { RemoteDevice = rd; Text = rd.IPAdd().ToString() + " - " + rd.ProductName; }
static void Main(string[] args) { Console.WriteLine("Starting"); IPEndPoint ep = new IPEndPoint(IPAddress.Parse("100.75.137.27"), 0xAF12); EnIPRemoteDevice OpENer = new EnIPRemoteDevice(ep); OpENer.autoConnect = true; OpENer.autoRegisterSession = true; // class 4, instance 151, attribut 3 : Config Data EnIPClass Class4 = new EnIPClass(OpENer, 4); EnIPInstance Instance151 = new EnIPInstance(Class4, 151); EnIPAttribut Config = new EnIPAttribut(Instance151, 3); // class 4, instance 150, attribut 3 : Output Data EnIPInstance Instance150 = new EnIPInstance(Class4, 150); EnIPAttribut Outputs = new EnIPAttribut(Instance150, 3); // class 4, instance 100, attribut 3 : Input Data EnIPInstance Instance100 = new EnIPInstance(Class4, 100); EnIPAttribut Inputs = new EnIPAttribut(Instance100, 3); // Read require, it provides the data size in the RawData field // If not, one have to make a new on it with the good size before // calling ForwardOpen : Inputs.RawData=new byte[xx] Config.ReadDataFromNetwork(); Inputs.ReadDataFromNetwork(); Outputs.ReadDataFromNetwork(); IPEndPoint LocalEp = new IPEndPoint(IPAddress.Any, 0x8AE); // It's not a problem to do this with more than one remote device, // the underlying udp socket is static OpENer.Class1Activate(LocalEp); // ForwardOpen in P2P, cycle 200 ms ForwardOpen_Config conf = new ForwardOpen_Config(Outputs, Inputs, true, 200 * 1000); // here can change conf for exemple to set Exclusive use, change priority or CycleTime not equal in the both direction // Attributes order cannot be changed, last optional attribute true // will write the config value Config.RawData (modifies it after ReadDataFromNetwork before this call) ForwardClose_Packet CloseData; EnIPNetworkStatus result = OpENer.ForwardOpen(Config, Outputs, Inputs, out CloseData, conf, false); if (result == EnIPNetworkStatus.OnLine) { // Register Inputs events to get notified Inputs.T2OEvent += new T2OEventHandler(Inputs_T2OEvent); Console.WriteLine("Running, hit a key to stop"); while (!Console.KeyAvailable) { Outputs.RawData[0] = (byte)(Outputs.RawData[0] + 1); Outputs.Class1UpdateO2T(); // must be called even if no data changed to maintain the link (Heartbeat) Thread.Sleep(200); } OpENer.ForwardClose(CloseData); } else { Console.WriteLine("Fail"); } }