Comments (6)
Ya, I've been working on generalizing the cpppo methods to more cleanly handle writes. It works fine (you can try it out using cpppo.server.enip.client via the Command-Line Interface (see docs). Remember to specify the data type as DINT, eg ... 'some_tag[0-3]=(DINT)0,1,2,3'
I have an experimental branch called 'feature-proxy-write' that is a work-in-progress, to get the cpppo.server.enip.get_attribute 'proxy' interface to cleanly handle both reading and writing. You could take a look at that.
I have been much too busy to work on this; some Cpppo "Support" contracts could help that... ;)
from cpppo.
Hello Sir,
Thanks a lot for your swift reply. Here is the python code; which tries to write an array of dints.
while True:
try:
with client.connector( host= plc_ip_address) as conn:
while True:
time_prev=time.time()
data = []
for c in range(5):
data.append(int(0))
req = conn.write("CDS_PLC_RawData_TLC", data,"DINT")
try:
rpy = next(conn)
print rpy
except AssertionError:
print "Response timed out!! Tearing Connection and Reconnecting!!!!!"
break
except AttributeError:
print "Tag J1_pos not written:::Will try again::"
break
Here is my error:
Traceback (most recent call last):
File "./tag_write.py", line 27, in
req = conn.write("CDS_PLC_RawData_TLC", data,"INT")
File "/usr/local/lib/python2.7/dist-packages/cpppo-3.9.4-py2.7.egg/cpppo/server/enip/client.py", line 701, in write
sender_context=sender_context )
File "/usr/local/lib/python2.7/dist-packages/cpppo-3.9.4-py2.7.egg/cpppo/server/enip/client.py", line 766, in unconnected_send
us.request.input = bytearray( device.dialect.produce( us.request )) # eg. logix.Logix
File "/usr/local/lib/python2.7/dist-packages/cpppo-3.9.4-py2.7.egg/cpppo/server/enip/logix.py", line 423, in produce
result += UINT.produce( data.write_frag.elements )
File "/usr/local/lib/python2.7/dist-packages/cpppo-3.9.4-py2.7.egg/cpppo/server/enip/parser.py", line 172, in produce
return struct.pack( cls.struct_format, value )
struct.error: cannot convert argument to integer
Any thoughts?. Thank you.
from cpppo.
The conn.write API is pretty low level, and needs alot of detail information. This is usually provided by client.parse_operations:
>>> from cpppo.server.enip import client
>>> list(client.parse_operations([ "some_tag=(DINT)0,1,2,3"] ))
[{'path': [{'symbolic': 'some_tag'}], 'elements': 4, 'data': [0, 1, 2, 3], 'method': 'write', 'tag_type': 196}]
So, if you want to call it directly, supply:
from cpppo.server.enip import client
client.write( [{'path': [{'symbolic': 'some_tag'}], elements=len( data ), data=data, tag_type=client.enip.DINT.tag_type )
from cpppo.
Also; don't forget that there is a turn-around time, awaiting the response from the client device.
I've rewritten your example to be a bit more correct:
import socket
import time
from cpppo.server.enip import client
plc_ip_address = "127.0.0.1"
timeout = 5.0
while True:
try:
with client.connector( host= plc_ip_address, timeout=timeout ) as conn:
while True:
data = [int(0) for c in range( 5 )]
req = conn.write( "CDS_PLC_RawData_TLC", elements=len( data ), data=data,
tag_type=client.enip.DINT.tag_type )
rpy,ela = client.await( conn, timeout=timeout )
print rpy
except AssertionError:
print "Response timed out!! Tearing Connection and Reconnecting!!!!!"
except AttributeError:
print "Tag J1_pos not written:::Will try again::"
except socket.error as exc:
print "Couldn't send command: %s" % ( exc )
time.sleep( .1 )
All this is sort of taken care of, if you use the client.connector API's simple 'process' method. This performs all tag I/O (allows pipeline depth, multiple request packets, etc., if desired), and synchronously returns the list of response after all I/O is complete:
#
# Run simulator in another window:
# python -m cpppo.server.enip -va localhost --print CDS_PLC_RawData_TLC=DINT[4]
#
import socket
import time
import cpppo
from cpppo.server.enip import client
plc_ip_address = "127.0.0.1"
timeout = 5.0
import logging
#cpppo.log_cfg['level'] = logging.DETAIL
logging.basicConfig( **cpppo.log_cfg )
tags = ["CDS_PLC_RawData_TLC[0-3]=(DINT)0,1,2,3"]
while True:
try:
with client.connector( host=plc_ip_address, timeout=timeout ) as conn:
operations = client.parse_operations( tags )
failures,replies = conn.process(
operations=operations, timeout=timeout )
for rpy in replies:
print rpy
except Exception as exc:
print "EtherNet/IP I/O Failed: %s" % ( exc )
time.sleep( .1 )
from cpppo.
Hello Sir,
Thanks a lot for the code!!. It is working well :).
I have one more question; I have been using the client.main(["-a", plc_ip_address, Tag]) to write tags to PLC. I was looking for other write features; as it was not that quick as connector.write.
Connector.write is fast because it an unconnected send?.
from cpppo.
All EtherNet/IP CIP I/O in the Cpppo library use "Unconnected" sends. The key to faster I/O is to set up the connection, and then to use it without closing it. The client.main API always sets up, uses, and then closes a connection. By maintaining your own connection and then using it repeatedly, you get much higher transaction rates.
To improve this much, much further -- use the client.pipeline API. This allows you to issue multiple transaction requests, before receiving the transaction replies. You can keep the PLC "saturated" with requests, instead of letting it sit idle while you await the response to a previous request.
from cpppo.
Related Issues (20)
- Connection manager: unconnected send
- Receiving (not pulling or writing) data from AB Compact GuardLogix PLC
- Question: Getting single attribute
- Question: read an array of structures in one request
- Question: write to structure field
- CIP Class 0x66
- AssertionError on harvest HOT 1
- Simulate Omron Adapter
- (Question) Duplicate Responses to CIP Discovery Packet HOT 3
- Sending SINT write request using client results in error
- Python 3.11 import problem HOT 1
- Question: What is the meaning of "Tag communications capability"
- Question: CPPPO Server configuration as Generic Ethernet Module in Studio 5000
- Client import problem HOT 1
- SMC JXC91 write HOT 5
- Question: How to call vendor specific services?
- Question: How to send Instance Service "reset (0x05)" instead of "get_attributes_all (0x01)" using Cpppo? HOT 1
- AssertionError: Failed to receive any response
- Implicit (cyclic) communication for lower latency
- Can we have a simple example of writing a single register to a ControlLogix please
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cpppo.