Code Monkey home page Code Monkey logo

s7connector's Introduction

S7 PLC Connector for Java
Build Status

S7 PLC Connector for Java

Screenshot of Example Documentation created with Slate

Features

  • Connect to Siemens S7 PLCs using TCP Connection

  • Reading and Writing data from/to S7 PLCs

  • OSGi Support

  • PROFINET Support

  • Use directly from Maven Central

  • Apache License

Getting Started

Simple read/write example

	//Create connection
    S7Connector connector = 
            S7ConnectorFactory
            .buildTCPConnector()
            .withHost("10.0.0.220")
            .withType(1) //optional
            .withRack(0) //optional
            .withSlot(2) //optional
            .build();
                
	//Read from DB100 10 bytes
	byte[] bs = connector.read(DaveArea.DB, 100, 10, 0);

	//Set some bytes
	bs[0] = 0x00;
		
	//Write to DB100 10 bytes
	connector.write(DaveArea.DB, 101, 0, bs);

	//Close connection
	connector.close();

More in the Documentation

Maven directions

<dependency>
    <groupId>com.github.s7connector</groupId>
    <artifactId>s7connector</artifactId>
    <version>2.1</version>
</dependency>

Need Help? Found a bug?

Feel free to submit an issue. And, of course, feel free to submit pull requests with bug fixes or changes.

Contributors

Pull requests are always welcome. See CONTRIBUTING.md for details.

License

See LICENSE.txt file.

Special Thanks

This project is based on libnodave

s7connector's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

s7connector's Issues

Modify README

README needs to be modified in such a way that would better describe the project. I have an initial idea on how it would be.

===> At the top of README : A logo for S7Connector
===> Just below it: S7 Devices image(s)
===> Features in bullet points (one line per bullet item)
===> Documentation URL
===> Maven Support
===> Contributing to this Project (For this we need to add a link to CONTRIBUTING.md)

This would be really great to have the README updated in this similar way.

exception when last element of datablock is string

When I construct a datablock which has its last element of type string and attempt to read it via the serializer.dispense method I get the following exception: -

com.github.s7connector.exception.S7Exception: dispense
at com.github.s7connector.impl.serializer.S7SerializerImpl.dispense(S7SerializerImpl.java:157)
at com.ascari.s7.main$4.widgetSelected(main.java:225)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:252)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4131)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1055)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3944)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3547)
at com.ascari.s7.main.open(main.java:66)
at com.ascari.s7.main.main(main.java:51)
Caused by: java.lang.IllegalArgumentException: Result: the desired address is beyond limit for this PLC
at com.github.s7connector.impl.S7BaseConnection.checkResult(S7BaseConnection.java:55)
at com.github.s7connector.impl.S7BaseConnection.read(S7BaseConnection.java:101)
at com.github.s7connector.impl.S7BaseConnection.read(S7BaseConnection.java:93)
at com.github.s7connector.impl.S7BaseConnection.read(S7BaseConnection.java:93)
at com.github.s7connector.impl.serializer.S7SerializerImpl.dispense(S7SerializerImpl.java:154)
... 9 more

if I append the datablock with an additional non-string type, the read works successfully..

IllegalArgumentException when trying to dispense an array of byte

In our code base we use your (great) library to dispense from a bean class. It contains a field specified like this

	@S7Variable(type = S7Type.BYTE, byteOffset = 0, bitOffset = 0, arraySize = 10)
	public byte[] ourField = new byte[10];

We took your example as base:

But, when trying to dispense to that bean we get an IllegalArgumentException for that field. We found out that we had to use the type Byte instead of the primitive byte. Can you confirm/fix that?

Unable to determine connection dropdown

I'm trying to read data cyclically (every 500ms) from a Siemens PLC. In my code I create an instance of S7TCPConnector only once when I start the application, and I always use the same instance.
However, if the TCP connection is interrupted (simply by disconnecting the network cable from the PC), no exceptions are triggered when I call the read(..) method of S7Connect interface, and neither the S7Connect nor the S7TCPConnection class have any method available to verify that the TCP connection is still active. The read(..) method returns to me a bool[] with almost 0 filled,but it's impossible to discriminate if the input is valid or not.

Is it possible to make the read(..) method of the S7TCPConnection class throw an exception when it is called when the TCP connection is dead?

Help with reading

I'm trying to read a DINT in DB27, DBD12 but the values ​​always come up incorrect. can anybody help me?

Code:

TesteController.java

@RestController
@RequestMapping("/fabrica")
public class TesteController {

@GetMapping
public MyDataBean findAll() throws IOException, SocketException {
    S7Connector connector =
            S7ConnectorFactory
                    .buildTCPConnector()
                    .withPort(102)
                    .withRack(0) //optional
                    .withSlot(1) //optional
                    .withHost("192.168.0.1")
                    .build();
    S7Serializer serializer = S7SerializerFactory.buildSerializer(connector);
    MyDataBean data = serializer.dispense(MyDataBean.class, 27, 0);
    connector.close();
    return data;
}

}

MyDataBean.java

public class MyDataBean {
@S7Variable(byteOffset = 12, type= S7Type.DWORD)
public int myNumber;
}

libnodave dependency

It is mentioned that This project is based on libnodave but I couldn't find sources which are originated from libnodave. Would you kindly mention the sources from libnodave?

Reuse JDK 1.5's Semaphore

Instead of using custom Semaphores for concurrency, it is actually better to reuse the Java 5's inbuilt concurrent classes (Lock, ReentrantRead(Write)Lock, Semaphore etc)

License Correction

I am wondering about the license of this project as I can see that Apache License is mentioned in the Maven POM but the source codes include GNU GPL.

It would be very helpful to open source IoT frameworks to use this library if it can be supported with a more free license, for instance, Apache License or Eclipse Public License.

New Release Version

I am wondering when there will be a new version of this library available in Maven Central.

Major Code Refactoring

  • Add comprehensive comments to all sources
  • Add 'this' qualifier to unqualified field accesses
  • Add 'this' qualifier to unqualified method accesses
  • Convert control statement bodies to block
  • Convert 'for' loops to enhanced 'for' loops
  • Add final modifier to private fields
  • Add final modifier to method parameters
  • Add final modifier to local variables
  • Put expressions in parentheses
  • Remove unused imports
  • Remove unused local variables
  • Add missing '@OverRide' annotations
  • Add missing '@OverRide' annotations to implementations of interface methods
  • Add missing '@deprecated' annotations
  • Remove unnecessary casts
  • Remove unnecessary '$NON-NLS$' tags
  • Sort all members
  • Remove trailing white spaces on all lines
  • Correct indentation
  • Remove redundant type arguments
  • Format the source

Violation of NoDave Copyright Policy

I believe the NoDave headers must be restored as it is filed in #38. Instead of including classes from NoDave, we must rewrite the same thing using advanced libraries such as Guava or Apache Commons so that this library can be used without having any dependency on NoDave. In such a scenario, this library can be used in many open source IoT projects.

Exception when reading Byte Array

I am working with the annotations of your project. Till now, I was reading and writing various types of variables and they worked fine. Now, I try to read an array. The datablock looks like the following

arrayissue

I created a bean class with a variable:

	@S7Variable(type = S7Type.BYTE, byteOffset = 0, bitOffset = 0, arraySize = 100)
	public Byte[] ourField;

When I try to read the datablock I get the following error:
the desired address is beyond limit for this plc

When I remove the S7 array variables I do not get an error, so I assume that the errors are resulting from the array variables (reading the boolean Variables works fine!).
I know this issue but here the issue seems to be solved by using Byte instead of byte - this does not work for me (I tried both).

The PLC I am using is a S1200 and I am working with TIA portal V15

Unexpected function code in answer

Hi everyone,

I realy like this library. Unfortunately sometimes I get the following Exception:

java.lang.IllegalArgumentException: Result: Unexpected function code in answer

In a loop I request several bytes in serial like so:

bs0 = connector.read(DaveArea.DB, 0, 1, offset);

Am I doing something wrong?
Thanks.

Best regards,
Zuendelmeister

Add close connection functionality in Object.finalize()

Due to explicit disconnection of S7TCPConnection, it is highly likely that consumers might forget to call disconnect method to release resources. So, it is better to include disconnect method in Object.finalize(). Even though JVM doesn't confirm invoking finalize() at a certain point of time, it is usually a good practice.

Exception when storing a datablock containing a stirng

If I create the following bean for sending to a PLC

import com.github.s7connector.api.annotation.S7Variable;
import com.github.s7connector.impl.utils.S7Type;

public class TestBlock {
@S7Variable(byteOffset=0, bitOffset=0, type=S7Type.BYTE)
public byte b1;

@S7Variable(byteOffset=14, bitOffset=0, type=S7Type.BOOL)
public boolean b2;

}

and use the _serializer.store method, my PLC correctly reflects the data that was passed in the bean.

If I add a String to the bean e.g.

import com.github.s7connector.api.annotation.S7Variable;
import com.github.s7connector.impl.utils.S7Type;

public class TestBlock {
@S7Variable(byteOffset=0, bitOffset=0, type=S7Type.BYTE)
public byte b1;

@S7Variable(byteOffset=2, bitOffset=0, type=S7Type.STRING)
public String s1;

@S7Variable(byteOffset=14, bitOffset=0, type=S7Type.BOOL)
public boolean b2;

}

I get the following exception

com.github.s7connector.exception.S7Exception: store
at com.github.s7connector.impl.serializer.S7SerializerImpl.store(S7SerializerImpl.java:187)
at com.ascari.fiab.plc.PLCInterface.TestWrite(PLCInterface.java:172)
at com.ascari.fiab.main$2.widgetSelected(main.java:285)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:252)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4131)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1055)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3944)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3547)
at com.ascari.fiab.main.open(main.java:96)
at com.ascari.fiab.main.main(main.java:69)
Caused by: com.github.s7connector.exception.S7Exception: insertBytes
at com.github.s7connector.impl.serializer.S7SerializerImpl.insertBytes(S7SerializerImpl.java:131)
at com.github.s7connector.impl.serializer.S7SerializerImpl.store(S7SerializerImpl.java:183)
... 10 more
Caused by: java.lang.IllegalArgumentException: String to big: 5
at com.github.s7connector.impl.serializer.converter.StringConverter.insert(StringConverter.java:70)
at com.github.s7connector.impl.serializer.S7SerializerImpl.insertBytes(S7SerializerImpl.java:125)
... 11 more

Connect the s7-200 family failed, because the code remove the TCP243 protocol

When I user the s7connector to read/write data from the s7-200 device with the TCP protocol, the program often prompts that the socket connection failed(the pipeline broken), so I compared the source code of s7connector with libnodave and found that s7connector removed the TCP243 protocol. Now I made some changes to the latest version and made sure the s7connecor can support the s7-200 device. I tested the code on a real device and found no problems right now. So can I submit my code?

Write DZone blog post

It is better off to make this library known to the public as I believe it would be beneficial for IoT developers to make use of this library.

BitConverter.insert() does not handle false as bit value 0

Hey,

the BitConverter.insert() method does not handle boolean false values, it just ignores them.
It is therefore not possible to set a bit to 0.

if (value) {
byte bufValue = buffer[byteOffset];
bufValue |= (0x01 << bitOffset);
buffer[byteOffset] = bufValue;
}

@Test
public void testInsertFalseBits() {
	byte[] buffer = new byte[] { 0b0101_0101 };
	int expected =               0b0101_0100;
	new BitConverter().insert(false, buffer, 0, 0, 1);
	Assert.assertEquals(expected, (int) buffer[0]);
}

java.lang.AssertionError: expected:<84> but was:<85>

Regards, M.

Exception when Stype is DWORD

I have a trouble, when try read a DWORD, the documentation say a DWORD is a long type java but when i try read with long data, give a exception, the only way to read DWORD is a int data type for java.

and when i try write data on int value the exception is the same.

this work fine for read data:

@S7Variable(byteOffset=278, type=S7Type.DWORD)
public int tiempoDescanso;

that make the exception:

@S7Variable(byteOffset=278, type=S7Type.DWORD)
public long tiempoDescanso;

com.github.s7connector.exception.S7Exception: dispense
at com.github.s7connector.impl.serializer.S7SerializerImpl.dispense(S7SerializerImpl.java:145)
at com.mycompany.mavenproject1.helper.PlcHelper.readPlc(PlcHelper.java:39)
at com.mycompany.mavenproject1.principal.conecta(principal.java:281)
at com.mycompany.mavenproject1.principal.jButton1ActionPerformed(principal.java:324)
at com.mycompany.mavenproject1.principal.access$100(principal.java:21)
at com.mycompany.mavenproject1.principal$2.actionPerformed(principal.java:86)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:289)
at java.awt.Component.processMouseEvent(Component.java:6533)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
at java.awt.Component.processEvent(Component.java:6298)
at java.awt.Container.processEvent(Container.java:2236)
at java.awt.Component.dispatchEventImpl(Component.java:4889)
at java.awt.Container.dispatchEventImpl(Container.java:2294)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
at java.awt.Container.dispatchEventImpl(Container.java:2280)
at java.awt.Window.dispatchEventImpl(Window.java:2746)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.awt.EventQueue$4.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: com.github.s7connector.exception.S7Exception: extractBytes
at com.github.s7connector.impl.serializer.S7SerializerImpl.extractBytes(S7SerializerImpl.java:78)
at com.github.s7connector.impl.serializer.S7SerializerImpl.dispense(S7SerializerImpl.java:143)
... 42 more
Caused by: java.lang.ClassCastException: Cannot cast java.lang.Integer to java.lang.Long
at java.lang.Class.cast(Class.java:3369)
at com.github.s7connector.impl.serializer.converter.LongConverter.extract(LongConverter.java:34)
at com.github.s7connector.impl.serializer.S7SerializerImpl.extractBytes(S7SerializerImpl.ja

Error on Serializing an Object

Hi!
I use the following code:

	S7Serializer serializer = S7SerializerFactory.buildSerializer(connector);
	
	MyDataBean bean1 = new MyDataBean();
	
	//Set some values
	bean1.bit1 = true;
	bean1.myNumber = 123;
	

	serializer.store(bean1, 1, 23);
	
	MyDataBean bean2 = serializer.dispense(MyDataBean.class, 1, 23); //here the error occurs

I always get the error: on
Exception in thread "main" com.github.s7connector.exception.S7Exception: dispense
at com.github.s7connector.impl.serializer.S7SerializerImpl.dispense(S7SerializerImpl.java:145)
at HelloWorld.main(HelloWorld.java:84)
Caused by: java.lang.IllegalArgumentException: Result: the desired address is beyond limit for this PLC
at com.github.s7connector.impl.S7BaseConnection.checkResult(S7BaseConnection.java:55)
at com.github.s7connector.impl.S7BaseConnection.read(S7BaseConnection.java:101)
at com.github.s7connector.impl.serializer.S7SerializerImpl.dispense(S7SerializerImpl.java:142)
... 1 more

Do I have to configure anything in the TIA portal? Currently I have 7 int variables in the datablock. I decided to use the offest 23 to avoid any conflicts. Even if the "store" operation does not throw an error I can not see anything in the TIA Portal in the Monitor mode....

Thank you!

Serialization of long String fails

I am using the bean method for reading a string from a S7-1200:
public class MyBean {
@S7Variable(byteOffset=0, bitOffset=0, type=S7Type.STRING, size=254)
public String abc;
}

In TIA, I created a data block variable of type string which got by default a size of 256 bytes. I tested my application and it works fine - I can read the string. After doing some testing I found out that strings with 128characters or less work fine. However, if the string has more than 128 characters I get the following exception:
Exception in thread "SPSTest" com.github.s7connector.exception.S7Exception: dispense
at com.github.s7connector.impl.serializer.S7SerializerImpl.dispense(S7SerializerImpl.java:157)
at myProject.base.thread.Worker.run(S7Tester.java:43)
Caused by: com.github.s7connector.exception.S7Exception: extractBytes
at com.github.s7connector.impl.serializer.S7SerializerImpl.extractBytes(S7SerializerImpl.java:90)
at com.github.s7connector.impl.serializer.S7SerializerImpl.dispense(S7SerializerImpl.java:155)
... 4 more
Caused by: java.lang.NegativeArraySizeException
at com.github.s7connector.impl.serializer.converter.StringConverter.extract(StringConverter.java:32)
at com.github.s7connector.impl.serializer.S7SerializerImpl.extractBytes(S7SerializerImpl.java:70)
... 5 more

TIA portal allows to enter strings up to 254 (?) characters but S7Connector seems to be unable to deseralize them...
Do you have a hint for me?

Issue with LongConverter

Hello,

May I'm wrong but i'm running into an issue with DWORD(Long)
Example:
DB2:

Address     |  0  |  1   |  2  |  3  |
Values(hex) |  0  |  0   |  2  |  12 | = 530

bs = connector.read(DaveArea.DB, 2, 4, 0);
final Integer i = ((bs[3] << 0) & 0x000000FF) | 
				          ((bs[2] << 8) & 0x0000FF00) | 
				          ((bs[1] << 16) & 0x00FF0000) | 
				          ((bs[0] << 24) & 0xFF000000);

In LongConverter.java it's the other way round. This only works with unsigned integers.

Best Regards
Christoph

OSGi Support

It would be helpful if you can provide this library as an OSGi bundle so that it can be made available in lots of Open Source OSGi based IoT frameworks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.