def scan_message_router(tag_name, position, values, types): success_service = set() # Read Tag 0x4c read_tag = [tag_name + '[' + str(position) + ']'] with client.connector(host=PLC_HOST) as conn: for index, descr, op, reply, status, value in conn.pipeline( operations=client.parse_operations(read_tag), depth=2): pass if status == 0x00: success_service.add(0x4c) # Write Tag 0x4d write_tag = [ str(tag_name + '[' + str(position) + ']=' + "(" + types + ")" + str(values)) ] with client.connector(host=PLC_HOST) as conn: for index, descr, op, reply, status, value in conn.pipeline( operations=client.parse_operations(write_tag), depth=2): pass if status == 0x00: success_service.add(0x4d) print(("Class Message Router 0x02 supports specifics serives " + str(success_service))) return success_service
def test_read_tags(self): with client.connector(host=self.enip_server_tcp.addr, port=self.enip_server_tcp.port, timeout=4.0) as connection: tags = ['@22/1/1'] ops = self.attribute_operations(tags) for idx, dsc, op, rpy, sts, val in connection.pipeline(operations=ops): self.assertEqual(100, val[0])
def PLC_Connection(host,tags): retVal=[] with client.connector(host=host) as conn: for index,descr,op,reply,status,value in conn.pipeline( operations=client.parse_operations(tags),depth=2): retVal.append(value) return retVal
def test_hart_pass_thru_simulated(simulated_hart_gateway): """Simulated HART I/O card; always returns Pass-thru Init handle 99 (won't work on a real device)""" command, address = simulated_hart_gateway #address = ('127.0.0.1',44818) # If you run: python3 ./hart_test.py try: assert address, "Unable to detect HART EtherNet/IP CIP Gateway IP address" hio = client.connector(host=address[0], port=address[1]) operations = [ { "method": "service_code", "code": HART.PT_INI_REQ, "data": [1, 0], # HART: Read primary variable "data_size": 4 + 2, # Known response size: command,status,<payload> "path": '@0x%X/8' % (HART.class_id), # Instance 1-8 ==> HART Channel 0-7 }, { "method": "service_code", "code": HART.PT_QRY_REQ, "data": [99], # HART: Pass-thru Query handle "data_size": 4 + 5, # Known response size: 5 (units + 4-byte real in network order) "path": '@0x%X/8' % (HART.class_id), # Instance 1-8 ==> HART Channel 0-7 }, ] # Now, use the underlying client.connector to issue a HART "Read Dynamic Variable" Service Code cmdbuf = '' with hio: results = [] failures = 0 for idx, dsc, req, rpy, sts, val in hio.pipeline( operations=client.parse_operations(operations), **hart_kwds): log.normal("Client %s: %s --> %r: %s", hio, dsc, val, enip.enip_format(rpy)) if not val: log.warning( "Client %s harvested %d/%d results; failed request: %s", hio, len(results), len(operations), rpy) failures += 1 results.append((dsc, val, rpy)) #cmdbuf = command_logging( command, cmdbuf ) # assert failures == 0 # statuses represent HART I/O status, not CIP response status assert results[0][-1].init.status in ( 32, 33, 35) # 32 busy, 33 initiated, 35 device offline assert results[1][-1].query.status in ( 0, 34, 35) # 0 success, 34 running, 35 dead except Exception as exc: log.warning("Test terminated with exception: %s", exc) raise
def test_list_interfaces_udp(self): with client.connector(host=self.enip_server_udp.addr, port=self.enip_server_udp.port, timeout=4.0, udp=True, broadcast=True) as conn: conn.list_interfaces() response = self.await_cpf_response(conn, 'list_interfaces') self.assertDictEqual({'count': 0}, response)
def write_xv(): host = "192.168.0.22" #tags = [ "X_Test[0-9]", "X_Test[5]=(DINT)555", "X_Test[0-9]" ] tags = ["X_Test[2]=(DINT)65"] #data = [123] with client.connector( host=host ) as conn: for index,descr,op,reply,status,value in conn.pipeline( operations=client.parse_operations( tags ), depth=2 ): print( "%s: %20s: %s" % ( time.ctime(), descr, value ))
def test_write_tags(self): with client.connector(host=self.enip_server_tcp.addr, port=self.enip_server_tcp.port, timeout=4.0) as connection: tags = ['@22/1/1=(SINT)50', '@22/1/1'] ops = self.attribute_operations(tags) for idx, dsc, op, rpy, sts, val in connection.pipeline(operations=ops): if idx == 0: self.assertEqual(True, val) elif idx == 1: self.assertEqual(50, val[0])
def test_list_services_udp(self): with client.connector(host=self.enip_server_udp.addr, port=self.enip_server_udp.port, timeout=4.0, udp=True, broadcast=True) as connection: connection.list_services() response = self.await_cpf_response(connection, 'list_services') self.assertEqual( "Communications", response['item'][0]['communications_service']['service_name'])
def test_list_interfaces_udp(self): with client.connector(host=self.enip_server_udp.addr, port=self.enip_server_udp.port, timeout=4.0, udp=True, broadcast=True) as conn: conn.list_interfaces() # TODO: udp does not cleanly shutdown. We get OSError. while True: response, ela = client.await(conn, timeout=4.0) if response: self.assertDictEqual({'count': 0}, response['enip']['CIP']['list_interfaces']['CPF']) else: break
def test_list_interfaces_tcp(self): with client.connector(host=self.enip_server_tcp.addr, port=self.enip_server_tcp.port, timeout=4.0, udp=False, broadcast=False) as conn: conn.list_interfaces() conn.shutdown() while True: response, ela = client.await(conn, timeout=4.0) if response: self.assertDictEqual({'count': 0}, response['enip']['CIP']['list_interfaces']['CPF']) else: break
def test_list_identity_udp(self): with client.connector(host=self.enip_server_udp.addr, port=self.enip_server_udp.port, timeout=4.0, udp=True, broadcast=True) as connection: connection.list_identity() response = self.await_cpf_response(connection, 'list_identity') expected = self.enip_server_tcp.config.product_name self.assertEqual( expected, response['item'][0]['identity_object']['product_name'])
def test_list_interfaces_tcp(self): with client.connector( host=self.enip_server_tcp.addr, port=self.enip_server_tcp.port, timeout=4.0, udp=False, broadcast=False, ) as conn: conn.list_interfaces() conn.shutdown() response = self.await_cpf_response(conn, "list_interfaces") self.assertDictEqual({"count": 0}, response)
def test_list_identity_udp(self): with client.connector(host=self.enip_server_udp.addr, port=self.enip_server_udp.port, timeout=4.0, udp=True, broadcast=True) as connection: connection.list_identity() # TODO: udp does not cleanly shutdown. We get OSError. while True: response, ela = client.await(connection, timeout=4.0) if response: expected = self.enip_server_tcp.config.product_name self.assertEqual(expected, response['enip']['CIP']['list_identity']['CPF']['item'][0]['identity_object']['product_name']) else: break
def test_list_services_udp(self): # test udp with client.connector(host=self.enip_server_udp.addr, port=self.enip_server_udp.port, timeout=4.0, udp=True, broadcast=True) as connection: connection.list_services() # TODO: udp does not cleanly shutdown. We get OSError. while True: response, ela = client.await(connection, timeout=4.0) if response: self.assertEqual("Communications", response['enip']['CIP']['list_services']['CPF']['item'][0]['communications_service']['service_name']) else: break
def test_list_services_tcp(self): # test tcp with client.connector(host=self.enip_server_tcp.addr, port=self.enip_server_tcp.port, timeout=4.0, udp=False, broadcast=False) as connection: connection.list_services() connection.shutdown() while True: response, ela = client.await(connection, timeout=4.0) if response: self.assertEqual("Communications", response['enip']['CIP']['list_services']['CPF']['item'][0]['communications_service']['service_name']) else: break
def test_list_identity_tcp(self): # test tcp with client.connector(host=self.enip_server_tcp.addr, port=self.enip_server_tcp.port, timeout=4.0, udp=False, broadcast=False) as connection: connection.list_identity() connection.shutdown() while True: response, ela = client.await(connection, timeout=4.0) if response: expected = self.enip_server_tcp.config.product_name self.assertEqual(expected, response['enip']['CIP']['list_identity']['CPF']['item'][0]['identity_object']['product_name']) else: break
def test_list_identity_tcp(self): with client.connector( host=self.enip_server_tcp.addr, port=self.enip_server_tcp.port, timeout=4.0, udp=False, broadcast=False, ) as connection: connection.list_identity() connection.shutdown() response = self.await_cpf_response(connection, "list_identity") expected = self.enip_server_tcp.config.product_name self.assertEqual( expected, response["item"][0]["identity_object"]["product_name"])
def test_list_services_tcp(self): with client.connector( host=self.enip_server_tcp.addr, port=self.enip_server_tcp.port, timeout=4.0, udp=False, broadcast=False, ) as connection: connection.list_services() connection.shutdown() response = self.await_cpf_response(connection, "list_services") self.assertEqual( "Communications", response["item"][0]["communications_service"]["service_name"], )
def TagData(mode, tag_name, plc_addr): #Building a function with client.connector(host=plc_addr, port=44818, timeout=timeout) as conn: #Creates a UDP connection operations = client.parse_operations([tag_name]) if (mode == "wr"): failures, transactions = conn.process(operations=operations, depth=2, multiple=0, fragment=False, printing=False, timeout=timeout) #Write Tag elif (mode == "rd"): for index, descr, op, reply, status, value in conn.pipeline( operations=operations, depth=2): #Read tag poz = (value[0]) if value is None: print("None returned while reading %s from PLC %s " % (tag_name, plc_addr)) return poz
def render_GET(self, request): try: IP = request.args['IP'][0] cmd = request.args['cmd'][0] id = cmd if cmd == 'getspeed': TAGS = ['@15/61/1', 'INT'] # getspeed if cmd.isdigit(): TAGS = ["@15/61/1=(INT)%s" % cmd] # setspeed id = 'setspeed' if cmd == 'getstate': TAGS = ['@15/65/1', 'INT'] # getstate if cmd == 'off': TAGS = ["@15/65/1=(INT)0"] # setstateoff if cmd == 'on': TAGS = ["@15/65/1=(INT)97"] # setstateon vfdcon1 = client.connector(host=IP) resp = '' with vfdcon1: for index, descr, op, reply, status, value in vfdcon1.synchronous( operations=attribute_operations( TAGS, route_path=[], send_path='')): if value: print value if isinstance(value, list): resp = value[1] * 256 + value[0] print cmd, resp, type(resp) if cmd == 'getstate' and resp == 0: resp = 'OFF' if cmd == 'getstate' and resp == 97: resp = 'ON' if cmd == 'getspeed' and isinstance(resp, int): resp = resp / 10.0 if isinstance(value, bool): resp = value except: return json.dumps({'response': 'ERROR'}) else: return json.dumps({'cmd': id, 'response': str(resp)})
""" Example of using cpppo.server.enip EtherNet/IP CIP client API. To see the Tag operations succeed, fire up: python -m cpppo.server.enip Tag=DINT[10] """ import sys, logging import cpppo from cpppo.server.enip import address, client if __name__ == "__main__": logging.basicConfig( **cpppo.log_cfg ) #logging.getLogger().setLevel(logging.INFO) host = 'localhost' # Controller IP address port = address[1] # default is port 44818 depth = 1 # Allow 1 transaction in-flight multiple = 0 # Don't use Multiple Service Packet fragment = False # Don't force Read/Write Tag Fragmented timeout = 1.0 # Any PLC I/O fails if it takes > 1s printing = True # Print a summary of I/O tags = ["Tag[0-9]+16=(DINT)4,5,6,7,8,9", "@0x2/1/1", "Tag[3-5]"] with client.connector( host=host, port=port, timeout=timeout ) as connection: operations = client.parse_operations( tags ) failures,transactions = connection.process( operations=operations, depth=depth, multiple=multiple, fragment=fragment, printing=printing, timeout=timeout ) sys.exit( 1 if failures else 0 )
#!/usr/bin/env python2 from cpppo.server.enip import client import time host = "192.168.179.131" tags = ["SCADA[1]", "SCADA[2]"] with client.connector(host=host) as conn: for index, descr, op, reply, status, value in conn.pipeline( operations=client.parse_operations(tags), depth=2): print("%s: %20s: %s" % (time.ctime(), descr, value))
""" Example of using cpppo.server.enip EtherNet/IP CIP client API. To see the Tag operations succeed, fire up: python -m cpppo.server.enip Tag=DINT[10] """ import sys, logging import cpppo from cpppo.server.enip import (address, client) if __name__ == "__main__": logging.basicConfig( **cpppo.log_cfg ) #logging.getLogger().setLevel(logging.INFO) host = 'localhost' # Controller IP address port = address[1] # default is port 44818 depth = 1 # Allow 1 transaction in-flight multiple = 0 # Don't use Multiple Service Packet fragment = False # Don't force Read/Write Tag Fragmented timeout = 1.0 # Any PLC I/O fails if it takes > 1s printing = True # Print a summary of I/O tags = ["Tag[0-9]+16=(DINT)4,5,6,7,8,9", "@0x2/1/1", "Tag[3-5]"] with client.connector( host=host, port=port, timeout=timeout ) as connection: operations = client.parse_operations( tags ) failures,transactions = connection.process( operations=operations, depth=depth, multiple=multiple, fragment=fragment, printing=printing, timeout=timeout ) sys.exit( 1 if failures else 0 )
logging.basicConfig(**cpppo.log_cfg) addr = args.address.split(':') assert 1 <= len( addr ) <= 2, "Invalid --address [<interface>]:[<port>}: %s" % args.address addr = (str(addr[0]) if addr[0] else enip.address[0], int(addr[1]) if len(addr) > 1 and addr[1] else enip.address[1]) timeout = float(args.timeout) failures = 0 try: with client.connector(host=addr[0], port=addr[1], timeout=timeout, udp=args.udp, broadcast=args.broadcast) as connection: connection.list_services() if args.list_identity: connection.list_identity() if args.list_interfaces: connection.list_interfaces() connection.shutdown( ) # starts a client-initiated clean shutdown for TCP/IP while True: response, ela = client. await (connection, timeout=timeout) if response: print(enip.enip_format(response)) else: break # No response (None) w'in timeout or EOF ({})
#host = "192.168.0.22" #tags = "X_Test[5-7]" print("Start Reading PLC") # Read Items from Access Config file into List and strip /n with open('config.txt') as f: w = [word.strip() for word in f] l1 = str(w[1]) #print(l1) #PLC Ip Address: l3 = str(w[3]) #print(l3) #PLC Tags: host = (l1) tags = [l3] with client.connector( host=host ) as conn_w: req1 = conn_w.write('X_Text[0-9]', data=[1,1,1,1,1,1,1,1,1,1]) req2 = conn_w.read('X_Text[0-9]') assert conn_w.readable( timeout=1.0 ), "Failed to receive reply 1" rpy1 = next( conn_w ) assert conn_w.readable( timeout=1.0 ), "Failed to receive reply 2" rpy2 = next( conn_w ) with client.connector (host=host) as conn_r: for index, descr, op, reply, status, value in conn_r.pipeline( operations=client.parse_operations(tags), depth=2): print("%20s: %s" % (descr, value)) raw=("%s" % (value[2])) plcValue1=(raw) print(raw)
} cpppo.log_cfg['level'] = ( levelmap[args.verbose] if args.verbose in levelmap else logging.DEBUG ) logging.basicConfig( **cpppo.log_cfg ) addr = args.address.split(':') assert 1 <= len( addr ) <= 2, "Invalid --address [<interface>]:[<port>}: %s" % args.address addr = ( str( addr[0] ) if addr[0] else enip.address[0], int( addr[1] ) if len( addr ) > 1 and addr[1] else enip.address[1] ) timeout = float( args.timeout ) failures = 0 try: with client.connector( host=addr[0], port=addr[1], timeout=timeout, udp=args.udp, broadcast=args.broadcast ) as connection: connection.list_services() if args.list_identity: connection.list_identity() if args.list_interfaces: connection.list_interfaces() connection.shutdown() # starts a client-initiated clean shutdown for TCP/IP while True: response,ela = client.await( connection, timeout=timeout ) if response: print( enip.enip_format( response )) else: break # No response (None) w'in timeout or EOF ({}) except Exception as exc: failures = 1
def test_hart_simple(simulated_hart_gateway): # No Multiple Service Packet supported by HART I/O Card simulator command, address = simulated_hart_gateway #address = ("127.0.0.1", 44818) #address = ("100.100.102.10", 44818) route_path = None route_path = [{'link': 2, 'port': 1}] try: assert address, "Unable to detect HART EtherNet/IP CIP Gateway IP address" hio = client.connector(host=address[0], port=address[1]) # Establish an Implicit EtherNet/IP CIP connection using Forward Open #hio = client.implicit( host=address[0], port=address[1], connection_path=None ) PV = 1.23 operations = [ { "method": "service_code", "code": HART.RD_VAR_REQ, "data": [], # No payload "data_size": 4 + 36, # Known response size: command,status,<payload> "path": '@0x%X/8' % (HART.class_id), # Instance 1-8 ==> HART Channel 0-7 }, 'HART_7_Data.PV = (REAL)0', # would fail 'til first HART Read Dynamic Variable is done { "method": "service_code", "code": HART.RD_VAR_REQ, "data": [], # No payload "data_size": 4 + 36, # Known response size: command,status,<payload> "path": '@0x%X/8' % (HART.class_id), # Instance 1-8 ==> HART Channel 0-7 }, 'HART_7_Data.PV = (REAL)%s' % PV, { "method": "service_code", "code": HART.RD_VAR_REQ, "data": [], # No payload "data_size": 4 + 36, # Known response size: command,status,<payload> "path": '@0x%X/8' % (HART.class_id), # Instance 1-8 ==> HART Channel 0-7 }, ] # Now, use the underlying client.connector to issue a HART "Read Dynamic Variable" Service Code simout = '' with hio: results = [] failures = 0 for idx, dsc, req, rpy, sts, val in hio.pipeline( operations=client.parse_operations(operations, route_path=route_path), **hart_kwds): log.normal("Client %s: %s --> %r: %s", hio, dsc, val, enip.enip_format(rpy)) if not val: log.warning( "Client %s harvested %d/%d results; failed request: %s", hio, len(results), len(operations), rpy) failures += 1 results.append((dsc, val, rpy)) rpylast = results[-1][-1] assert failures in (0, 1) assert near(rpylast.read_var.PV, PV) except Exception as exc: log.warning("Test terminated with exception: %s", exc) raise
def test_hart_pass_thru_poll(simulated_hart_gateway): r"""To test a remote C*Logix w/ a HART card, set up a remote port forward from another host in the same LAN. Here's a windows example, using putty. This windows machine (at 100.100.102.1) forwards a port 44818 on fat2.kundert.ca, to the PLC at 100.100.102.10:44818: C:\Users\Engineer\Desktop\putty.exe -R 44818:100.100.102.10:44818 [email protected] Now, from another host that can see fat2.kundert.ca: $ python -m cpppo.server.enip.list_services --list-identity -a fat2.kundert.ca:44818 { "peer": [ "fat2.kundert.ca", 44818 ], ... "enip.status": 0, "enip.CIP.list_services.CPF.count": 1, "enip.CIP.list_services.CPF.item[0].communications_service.capability": 288, "enip.CIP.list_services.CPF.item[0].communications_service.service_name": "Communications", } { ... "enip.status": 0, "enip.CIP.list_identity.CPF.item[0].identity_object.sin_addr": "100.100.102.10", "enip.CIP.list_identity.CPF.item[0].identity_object.status_word": 96, "enip.CIP.list_identity.CPF.item[0].identity_object.vendor_id": 1, "enip.CIP.list_identity.CPF.item[0].identity_object.product_name": "1756-EN2T/D", "enip.CIP.list_identity.CPF.item[0].identity_object.sin_port": 44818, "enip.CIP.list_identity.CPF.item[0].identity_object.state": 3, "enip.CIP.list_identity.CPF.item[0].identity_object.version": 1, "enip.CIP.list_identity.CPF.item[0].identity_object.device_type": 12, "enip.CIP.list_identity.CPF.item[0].identity_object.sin_family": 2, "enip.CIP.list_identity.CPF.item[0].identity_object.serial_number": 11866067, "enip.CIP.list_identity.CPF.item[0].identity_object.product_code": 166, "enip.CIP.list_identity.CPF.item[0].identity_object.product_revision": 1802, } """ command, address = simulated_hart_gateway # For testing, we'll hit a specific device #address = ("fat2.kundert.ca", 44818) #address = ("100.100.102.10", 44818) #address = ("localhost", 44818) route_path = None route_path = [{'link': 2, 'port': 1}] try: assert address, "Unable to detect HART EtherNet/IP CIP Gateway IP address" #hio = client.implicit( host=address[0], port=address[1] ) hio = client.connector(host=address[0], port=address[1]) # Just get the primary variable, to see if the HART device is there. operations = [ { "method": "service_code", "code": HART.RD_VAR_REQ, "data": [], # No payload "data_size": 4 + 36, # Known response size: command,status,<payload> "path": '@0x%X/8' % (HART.class_id), # Instance 1-8 ==> HART Channel 0-7 "route_path": route_path, }, ] with hio: for idx, dsc, req, rpy, sts, val in hio.pipeline( operations=client.parse_operations(operations), **hart_kwds): log.normal("Client %s: %s --> %r: %s", hio, dsc, val, enip.enip_format(rpy)) path = '@0x%X/8' % (HART.class_id) data = hart_pass_thru(hio, path=path, hart_data=[1, 0], route_path=route_path, data_size=4) # with no size # The small response carries the 4-byte value, the long CIP MSG response additionally # carries the data type We receive the long response. value = None if data and len(data) >= 4: units = data[0] if len(data) > 4 else None packer = struct.Struct(enip.REAL_network.struct_format) value, = packer.unpack_from(buffer=bytearray(data[-4:])) log.normal("Read primary variable Value: %s (units: %s), from: %r", value, units, data) # HART Command 3 gets all 4 variables data = hart_pass_thru(hio, path=path, hart_data=[3, 0], route_path=route_path, data_size=4 * 4) # with no size # small response carries PV, SV, TV, FV values, no data types value = [] if data and len(data) == 4 * 4: # Short packer = struct.Struct(enip.REAL_network.struct_format) for i in range(0, len(data), 4): value += packer.unpack_from(buffer=bytearray(data[i:i + 4])) elif data and len(data) >= 24: # Long packer = struct.Struct(enip.REAL_network.struct_format) value = cpppo.dotdict() value.current, = packer.unpack_from(buffer=bytearray(data[0:])) value.PV_units = data[4] value.PV, = packer.unpack_from(buffer=bytearray(data[5:])) value.SV_units = data[10] value.SV, = packer.unpack_from(buffer=bytearray(data[11:])) value.TV_units = data[14] value.TV, = packer.unpack_from(buffer=bytearray(data[15:])) value.FV_units = data[19] value.FV, = packer.unpack_from(buffer=bytearray(data[20:])) log.normal("Read all variables Values: %s, from: %r", enip.enip_format(value), data) # HART Command 12 gets the 24-character Message data = hart_pass_thru(hio, path=path, hart_data=[12, 0], route_path=route_path, data_size=4 * 4) # with no size value = None if data and len(data): try: value = bytes(data).decode('ascii') except: value = hexdump(data) log.normal("Read Message: \n%s\nfrom: %r", value, data) # HART Command 0 gets the identity data = hart_pass_thru(hio, path=path, hart_data=[0, 0], route_path=route_path, data_size=4 * 4) # with no size value = None if data and len(data): value = hexdump(data) log.normal("Read Identity: \n%s\nfrom: %r", value, data) # HART Command 13 gets the Tag data = hart_pass_thru(hio, path=path, hart_data=[13, 0], route_path=route_path, data_size=4 * 4) # with no size value = None if data and len(data): value = hexdump(data) log.normal("Read Tag: \n%s\nfrom: %r", value, data) except Exception as exc: log.warning("Test terminated with exception: %s", exc) raise
help="Hostname of target Controller") ap.add_argument('-t', '--timeout', default=None, help="I/O timeout seconds (default: None)") ap.add_argument('tags', nargs='+', help="Tags to read/write") args = ap.parse_args() depth = int(args.depth) multiple = int(args.multiple) repeat = int(args.repeat) operations = client.parse_operations(args.tags * repeat) timeout = None if args.timeout is not None: timeout = float(args.timeout) with client.connector(host=args.address, timeout=timeout) as conn: start = cpppo.timer() num, idx = -1, -1 for num, (idx, dsc, op, rpy, sts, val) in enumerate( conn.pipeline(operations=operations, depth=depth, multiple=multiple, timeout=timeout)): print("%s: %3d: %s" % (timestamp(), idx, val)) elapsed = cpppo.timer() - start print( "%3d operations using %3d requests in %7.2fs at pipeline depth %2s; %5.1f TPS" % (num + 1, idx + 1, elapsed, args.depth, num / elapsed))
def operate(host='localhost', port=44818, tags=[], udp=False, broadcast=False, timeout=5, repeat=1, depth=1, fragment=False, route_path=None, send_path='', simple=False, multiple=False, priority_time_tick=5, timeout_ticks=157): """ Read/write specified EthernetIP tags Function arguments are similar to cpppo.server.enip.client command line arguments. Args: host: host to connect (default: localhost) port: port to connect (44818) tags: list of tag operations, e.g. TAG1, TAG2[0-2], TAG3[5]=5, TAG4=77.99 (refer to client CLI for more help) udp: use UDP/IP (default: False) broadcast: allow multiple peers, and use of broadcast address (default: False) timeout: EIP timeout (default: 5s) repeat: times to repeat request (default: 1) depth: pipeline requests to this depth (default: 1) fragment: always use read/write tag fragmented requests (default: False) route_path: <port>/<link> or JSON (default: '[{"port": 1, "link": 0}]'); 0/false to specify no/empty route_path send_path: send Path to UCMM (default: @6/1); specify an empty string '' for no send path simple: access a simple (non-routing) EIP CIP device (eg. MicroLogix, default: False) multiple: use multiple service packet request targeting ~500 bytes (default: False) priority_time_tick: timeout tick length N range (0,15) (default: 5 == 32), where each tick is 2**N ms. Eg. 0 ==> 1ms., 5 ==> 32ms., 15 ==> 32768ms timeout_ticks: timeout duration ticks in range (1,255) (default: 157 == 5024ms) Returns: tuple (result, failures) where result is a list of operation results (lists for get, True for set) and failures is a number of failed operations Raises: socket exceptions if connection has been failed """ addr = (host, port) multiple = 500 if multiple else 0 # route_path may be None/0/False/'[]', send_path may be None/''/'@2/1'. # simple designates '[]', '' respectively, appropriate for non-routing CIP # devices, eg. MicroLogix, PowerFlex, ... route_path = device.parse_route_path( route_path ) if route_path \ else [] if simple else None send_path = send_path if send_path \ else '' if simple else None failures = 0 transactions = [] with connector(host=addr[0], port=addr[1], timeout=timeout, udp=udp, broadcast=broadcast) as connection: if tags: operations = parse_operations( recycle(tags, times=repeat), route_path=route_path, send_path=send_path, timeout_ticks=timeout_ticks, priority_time_tick=priority_time_tick) failed, transactions = connection.process(operations=operations, depth=depth, multiple=multiple, fragment=fragment, printing=False, timeout=timeout) failures += failed return transactions, failures
if __name__ == "__main__": ap = argparse.ArgumentParser() ap.add_argument( '-d', '--depth', default=0, help="Pipelining depth" ) ap.add_argument( '-m', '--multiple', default=0, help="Multiple Service Packet size limit" ) ap.add_argument( '-r', '--repeat', default=1, help="Repeat requests this many times" ) ap.add_argument( '-a', '--address', default='localhost', help="Hostname of target Controller" ) ap.add_argument( '-t', '--timeout', default=None, help="I/O timeout seconds (default: None)" ) ap.add_argument( 'tags', nargs='+', help="Tags to read/write" ) args = ap.parse_args() depth = int( args.depth ) multiple = int( args.multiple ) repeat = int( args.repeat ) operations = client.parse_operations( args.tags * repeat ) timeout = None if args.timeout is not None: timeout = float( args.timeout ) with client.connector( host=args.address, timeout=timeout ) as conn: start = cpppo.timer() num,idx = -1,-1 for num,(idx,dsc,op,rpy,sts,val) in enumerate( conn.pipeline( operations=operations, depth=depth, multiple=multiple, timeout=timeout )): print( "%s: %3d: %s" % ( timestamp(), idx, val )) elapsed = cpppo.timer() - start print( "%3d operations using %3d requests in %7.2fs at pipeline depth %2s; %5.1f TPS" % ( num+1, idx+1, elapsed, args.depth, num / elapsed ))
logging.basicConfig(**cpppo.log_cfg) addr = args.address.split(':') assert 1 <= len( addr ) <= 2, "Invalid --address [<interface>]:[<port>}: %s" % args.address addr = (str(addr[0]) if addr[0] else enip.address[0], int(addr[1]) if len(addr) > 1 and addr[1] else enip.address[1]) timeout = float(args.timeout) failures = 0 try: with client.connector( host=addr[0], port=addr[1], timeout=timeout, udp=args.udp, broadcast=args.broadcast, source_address=args.source_address) as connection: connection.list_services() if args.list_identity: connection.list_identity() if args.list_interfaces: connection.list_interfaces() connection.shutdown( ) # starts a client-initiated clean shutdown for TCP/IP while True: response, ela = client. await (connection, timeout=timeout) if response: print(enip.enip_format(response)) else:
cpppo.log_cfg['level'] = ( levelmap[args.verbose] if args.verbose in levelmap else logging.DEBUG ) logging.basicConfig( **cpppo.log_cfg ) addr = args.address.split(':') assert 1 <= len( addr ) <= 2, "Invalid --address [<interface>]:[<port>}: %s" % args.address addr = ( str( addr[0] ) if addr[0] else enip.address[0], int( addr[1] ) if len( addr ) > 1 and addr[1] else enip.address[1] ) timeout = float( args.timeout ) failures = 0 try: with client.connector( host=addr[0], port=addr[1], timeout=timeout, udp=args.udp, broadcast=args.broadcast, source_address=args.source_address ) as connection: connection.list_services() if args.list_identity: connection.list_identity() if args.list_interfaces: connection.list_interfaces() connection.shutdown() # starts a client-initiated clean shutdown for TCP/IP while True: response,ela = client.await( connection, timeout=timeout ) if response: print( enip.enip_format( response )) else: break # No response (None) w'in timeout or EOF ({}) except Exception as exc:
# -*- coding: utf-8 -*- """ Created on Mon Jul 25 09:37:02 2016 @author: avieux """ from __future__ import print_function from cpppo.server.enip import client import time host = "192.168.0.22" tags = ["PyComm_Read1[0-9]"] with client.connector( host=host ) as conn: req1 = conn.write( "PyComm_Read1[0-2]", data=[1,1,1] ) req2 = conn.read( "PyComm_Read1[2]" ) assert conn.readable( timeout=1.0 ), "Failed to receive reply 1" rpy1 = next( conn ) assert conn.readable( timeout=1.0 ), "Failed to receive reply 2" rpy2 = next( conn )
# {'port':1, 'link': 0}, # {'class':2}, {'instance':1}, # #{'class':1}, {'instance':1},# {'attribute':7}, # #{'symbolic': 'A63FGRDT'} # ], # path = [ # # {'symbolic': 'A63FGRDT'}, # {'class':1}, {'instance':1},# {'attribute':7}, # ] ) else: route_path, send_path = None, None # Routed (eg. C*Logix) #route_path, send_path = defaults.route_path_default, defaults.send_path_default connection = client.connector( host = hostname, timeout = timeout, sender_context = sender_context, ) with connection as conn: data = True while True: # Perform some I/O on the Connected channel begun = cpppo.timer() operations = client.parse_operations( params, route_path=route_path, send_path=send_path ) failed,txs = conn.process( operations=operations, depth=depth, multiple=multiple, fragment=fragment, printing=printing, timeout=timeout ) elapsed = cpppo.timer() - begun
sock.bind(server_address) # Listen for incoming connections sock.listen(1) # Receive the data in small chunks and retransmit it while True: # establish a connection clientsocket, addr = sock.accept() print("Got a connection from %s" % str(addr)) #rand = random.randint(1,100) #msg = str(rand) #clientsocket.send(msg.encode('ascii')) #machine data try: with client.connector(host=host, timeout=timeout) as conn: for index, descr, op, reply, status, value in conn.pipeline( operations=client.parse_operations(tags), depth=1): if (index == 0): A = value[0] #machine ID if (index == 1): B = value[0] #machine Count except OSError as err: A = "8" except ValueError: print("Could not convert data to an integer.") except: print("Unexpected error:", sys.exc_info()[0]) raise if (A == "X"):