Exemple #1
0
def test_powerflex_poll_success(simulated_powerflex_gateway):
    #logging.getLogger().setLevel( logging.INFO )
    command, address = simulated_powerflex_gateway
    try:
        assert address, "Unable to detect PowerFlex EtherNet/IP CIP Gateway IP address"
        values = {}

        def process(p, v):
            print("%s: %16s == %s" % (time.ctime(), p, v))
            values[p] = v

        process.done = False

        poller = threading.Thread(target=poll.poll,
                                  args=(powerflex_750_series, ),
                                  kwargs={
                                      'address': address,
                                      'cycle': 1.0,
                                      'timeout': 0.5,
                                      'process': process,
                                  })
        poller.deamon = True
        poller.start()

        try:
            # Polling starts immediately
            time.sleep(.5)
            assert len(values) == 2

            # Make sure it repeats
            values.clear()
            assert len(values) == 0
            time.sleep(1.0)
            assert len(values) == 2

            # Allow time to refresh values on next poll
            values['Output Current'] = 1.0
            time.sleep(1.0)
        finally:
            process.done = True

        poller.join(1.0)
        assert not poller.is_alive(), "Poller Thread failed to terminate"

        assert 'Output Current' in values and near(values['Output Current'][0],
                                                   123.45)
        assert 'Motor Velocity' in values and near(values['Motor Velocity'][0],
                                                   789.01)

    except Exception as exc:
        logging.warning("Test terminated with exception: %s", exc)
        raise
Exemple #2
0
def test_powerflex_poll_success( simulated_powerflex_gateway ):
    #logging.getLogger().setLevel( logging.INFO )
    command,address             = simulated_powerflex_gateway
    try:
        assert address, "Unable to detect PowerFlex EtherNet/IP CIP Gateway IP address"
        values			= {}
        def process( p, v ):
            print( "%s: %16s == %s" % ( time.ctime(), p, v ))
            values[p]		= v    
        process.done		= False
    
        poller			= threading.Thread(
            target=poll.poll, args=(powerflex_750_series,), kwargs={ 
                'address': 	address,
                'cycle':	1.0,
                'timeout':	0.5,
                'process':	process,
            })
        poller.deamon		= True
        poller.start()

        try:
            # Polling starts immediately
            time.sleep(.5)
            assert len( values ) == 2

            # Make sure it repeats
            values.clear()
            assert len( values ) == 0
            time.sleep(1.0)
            assert len( values ) == 2

            # Allow time to refresh values on next poll
            values['Output Current'] = 1.0
            time.sleep(1.0)
        finally:
            process.done	= True

        poller.join( 1.0 )
        assert not poller.is_alive(), "Poller Thread failed to terminate"
    
        assert 'Output Current' in values and near( values['Output Current'][0], 123.45 )
        assert 'Motor Velocity' in values and near( values['Motor Velocity'][0], 789.01 )

    except Exception as exc:
        logging.warning( "Test terminated with exception: %s", exc )
        raise
Exemple #3
0
def test_powerflex_simple( simulated_powerflex_gateway ):
    #logging.getLogger().setLevel( logging.INFO )
    command,address             = simulated_powerflex_gateway
    try:
        assert address, "Unable to detect PowerFlex EtherNet/IP CIP Gateway IP address"
        pf				= powerflex( host=address[0], port=address[1], timeout=1 )

        # Reading a list of nothing should work...
        assert list( pf.read( [] )) == []
        # At the least, it ensures we have a non-None .identity
        print( "PowerFlex Identity: %s" % pf )
        assert "None" not in str( pf ), "No EtherNet/IP CIP connection, or no Identity"

        # Simple read of Tag, using Read Tag; returns list of bare list of data elements
        tag			= "SCADA[0-9]"
        value,			= pf.read( [ tag ] )
        print( "Tag:            %15s: %r" % ( tag, value ))
        assert type( value ) is list and all( v == 0 for v in value )

        # Read of CIP Object/Instance/Attribute using Get Attribute Single, interpreted as an
        # arbitrary CIP data type.  Returns list of result values, each a dict of decoded data.
        # Providing a type to use to decode the data produces whatever dictionary the type parses
        # into, unchanged:
        get			= ( "@1/1/1", enip.INT )
        value,			= pf.read( [ get ] )
        print( "Vendor Number:  %15s: %r" % ( get[0], value ))
        assert len( value ) == 1 and 'INT' in value[0] and value[0]['INT'] == 0x0001

        get			= ( "@1/1/7", enip.SSTRING )
        value,			= pf.read( [ get] )
        print( "Product Name:   %15s: %r" % ( get[0], value ))
        assert len( value ) == 1 and 'SSTRING' in value[0] and value[0].SSTRING.string == 'PowerFlex/20-COMM-E'

        # Get the DPI Parameter 0x93, Instance 3, Attribute 9 Output_Current attribute, interpreted
        # as REAL.  1 element.
        get			= ( "@0x93/7/10", enip.REAL )
        value,			= pf.read( [ get] )
        print( "Output_Current: %15s: %r" % ( get[0], value ))
        assert len( value ) == 1 and 'REAL' in value[0] and near( value[0].REAL, 123.45 )

        # Get the DPI parameter 0x93, Instance 3, Attribute 9 Output_Current attribute, interpreted
        # as INT.  1 element.  Providing named CIP types shucks the dictionary container, and
        # produces just the target typed data:
        get			= ( "@0x93/140/10", "INT" )
        value,			= pf.read( [ get] )
        print( "Accel_Time_1:   %15s: %r" % ( get[0], value ))
        assert len( value ) == 1 and value[0] == 567
        get			= ( "@1/1", [ "INT", "INT", "INT", "INT", "INT", "DINT", "SSTRING", "USINT" ])
        value,			= pf.read( [ get] )
        print( "Identity (all): %15s: %r" % ( get[0], value ))
        assert value == [1, 14, 54, 2836, 12640, 7079450, u'PowerFlex/20-COMM-E', 255]

        # TCPIP Object
        get			= ( "@0xF5/1", [
            "DWORD", "DWORD", "DWORD", "EPATH",
            "IPADDR", "IPADDR", "IPADDR", "IPADDR", "IPADDR", "STRING",
            "STRING"
            ])
        value,			= pf.read( [ get] )
        print( "TCPIP (all):    %15s: %r" % ( get[0], value ))
        assert value == [2, 48, 16, [{'class': 246}, {'instance': 1}], '10.0.0.4', '255.255.252.0', '10.0.0.1', '10.0.0.1', '8.8.8.8', u'example.com', u'powerflex']
        
        # List Identity
        ident			= pf.list_identity()
        assert ident.sin_addr == "10.0.0.4"

    except Exception as exc:
        logging.warning( "Test terminated with exception: %s", exc )
        raise
Exemple #4
0
def test_powerflex_simple( simulated_powerflex_gateway ):
    # logging.getLogger().setLevel( logging.INFO )
    command,address             = simulated_powerflex_gateway
    try:
        assert address, "Unable to detect PowerFlex EtherNet/IP CIP Gateway IP address"
        pf				= powerflex( host=address[0], port=address[1], timeout=1 )

        # Reading a list of nothing should work...
        assert list( pf.read( [] )) == []
        # At the least, it ensures we have a non-None .identity
        print( "PowerFlex Identity: %s" % pf )
        assert "None" not in str( pf ), "No EtherNet/IP CIP connection, or no Identity"

        # Simple read of Tag, using Read Tag; returns list of bare list of data elements
        tag			= "SCADA[0-9]"
        value,			= pf.read( [ tag ] )
        print( "Tag:            %15s: %r" % ( tag, value ))
        assert type( value ) is list and all( v == 0 for v in value )

        # Read of CIP Object/Instance/Attribute using Get Attribute Single, interpreted as an
        # arbitrary CIP data type.  Returns list of result values, each a dict of decoded data.
        # Providing a type to use to decode the data produces whatever dictionary the type parses
        # into, unchanged:
        get			= ( "@1/1/1", enip.INT )
        value,			= pf.read( [ get ] )
        print( "Vendor Number:  %15s: %r" % ( get[0], value ))
        assert len( value ) == 1 and 'INT' in value[0] and value[0]['INT'] == 0x0001

        get			= ( "@1/1/7", enip.SSTRING )
        value,			= pf.read( [ get] )
        print( "Product Name:   %15s: %r" % ( get[0], value ))
        assert len( value ) == 1 and 'SSTRING' in value[0] and value[0].SSTRING.string == 'PowerFlex/20-COMM-E'

        # Get the DPI Parameter 0x93, Instance 3, Attribute 9 Output_Current attribute, interpreted
        # as REAL.  1 element.
        get			= ( "@0x93/7/10", enip.REAL )
        value,			= pf.read( [ get] )
        print( "Output_Current: %15s: %r" % ( get[0], value ))
        assert len( value ) == 1 and 'REAL' in value[0] and near( value[0].REAL, 123.45 )

        # Get the DPI parameter 0x93, Instance 3, Attribute 9 Output_Current attribute, interpreted
        # as INT.  1 element.  Providing named CIP types shucks the dictionary container, and
        # produces just the target typed data:
        get			= ( "@0x93/140/10", "INT" )
        value,			= pf.read( [ get] )
        print( "Accel_Time_1:   %15s: %r" % ( get[0], value ))
        assert len( value ) == 1 and value[0] == 567
        get			= ( "@1/1", [ "INT", "INT", "INT", "INT", "INT", "DINT", "SSTRING", "USINT" ])
        value,			= pf.read( [ get] )
        print( "Identity (all): %15s: %r" % ( get[0], value ))
        assert value == [1, 14, 54, 2836, 12640, 7079450, u'PowerFlex/20-COMM-E', 255]

        # TCPIP Object
        get			= ( "@0xF5/1", [
            "DWORD", "DWORD", "DWORD", "EPATH",
            "IPADDR", "IPADDR", "IPADDR", "IPADDR", "IPADDR", "STRING",
            "STRING"
            ])
        value,			= pf.read( [ get] )
        print( "TCPIP (all):    %15s: %r" % ( get[0], value ))
        assert value == [2, 48, 16, [{'class': 246}, {'instance': 1}], '10.0.0.4', '255.255.252.0', '10.0.0.1', '10.0.0.1', '8.8.8.8', u'example.com', u'powerflex']
        
        # List Identity
        ident			= pf.list_identity()
        assert ident.sin_addr == "10.0.0.4"

    except Exception as exc:
        logging.warning( "Test terminated with exception: %s", exc )
        raise
Exemple #5
0
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