Skip to main content

ETG.1510 EtherCAT Master Diagnosis Interface client library for Python

Project description

This package is client software that acquire diagnostic information from the EtherCAT master with vendor independent.

Various diagnostic information defined as the ETG.1510 SDO entries at the EtherCAT master, these are possible to be acquired via Mailbox Gateway (ETG.8200).

The EtherCAT master supports not a whole OD entries of ETG.1510 specified but a partially by each vendor, further the data size of VISIBLE_STRING types is not specified on ETG 1510.

Therefore, as first the client has to fetch SDO information by SDO information service due to know these information.

This package has the following features.

  1. Acquire object dictionaries (OD) from EtherCAT master by using SDO information service. And makes python dictionary type data with a valid SDO index as the key and SDO container as the value.
  2. Acquire diagnosis data from EtherCAT master using based on valid OD entries dictionary.

These data are possible to be acquired by python asynchronous iterator.

Installation

$ pip install pyetg1510

Connection

If you want to know connect to Mailbox Gateway host address, Please see homepage.

Quick start

# This is a sample Python script.
from pyetg1510 import EtherCATMasterConnection, MasterODSpecification, ETG1510Profile, SysLog, LoggingLevel
from dataclasses import fields
import asyncio
import sys
from socket import inet_aton
from pprint import pprint

async def get_etg1510_whole_data(etg1510: ETG1510Profile):
    """Get whole sdo data one time"""
    # Getting sdo data by ETG.1510 profile generator.
    async for entry, data in etg1510:
        pprint({hex(entry): {f.name: getattr(data, f.name).value for f in fields(data)}})

async def get_etg1510_data_frequently(etg1510: ETG1510Profile):
    """Get selected sdo data cyclically"""
    # Getting sdo data by ETG.1510 profile generator.
    watch_list = list(etg1510.sdo_database.keys())
    # only diagnosis data
    etg1510.watch_index_list = list(filter(lambda x: 0xA000 <= x <= 0xAFFF, watch_list))
    # Getting sdo data by ETG.1510 profile generator.
    while True:
        async for entry, data in etg1510:
            pprint({hex(entry): {f.name: getattr(data, f.name).value for f in fields(data)}})
            pprint({"PortStatus": data.port_status})
            pprint({"ALStatusCode": data.al_status_code})
            pprint({"ALControl": data.al_control})
            pprint({"ALStatus": data.al_status})
            pprint({"Is Rejected?": data.is_rejected})
            pprint({"Is Updated?": data.is_updated})
        await asyncio.sleep(0.3)

async def get_etg1510_data(etg1510: ETG1510Profile, index: int = 0xA000):
    """Get specified index sdo data"""
    # get SDO data of index default 0xA001.
    sdo = await etg1510.get_sdo(index)
    pprint({hex(index): {f.name: getattr(sdo, f.name).value for f in fields(sdo)}})
    pprint({"PortStatus": sdo.port_status})
    pprint({"ALStatusCode": sdo.al_status_code})
    pprint({"ALControl": sdo.al_control})
    pprint({"ALStatus": sdo.al_status})
    pprint({"Is Rejected?": sdo.is_rejected})
    pprint({"Is Updated?": sdo.is_updated})

# Press the green button in the gutter to run the script.
if __name__ == "__main__":
    # logging settings
    SysLog.console_log_configuration(LoggingLevel.DISABLE)
    SysLog.syslog_configuration(LoggingLevel.DISABLE)
    SysLog.rotation_log_configuration(LoggingLevel.WARNING)
    SysLog.set_loglevel(LoggingLevel.WARNING)

    # Get target ip address from command argument
    def is_valid_ip(addr):
        try:
            inet_aton(addr)
            return True
        except:
            return False

    args = sys.argv
    if len(args) < 2:
        print("Please specify ip address of mailbox gateway.")
        exit(-1)
    elif not is_valid_ip(args[1]):
        print(f"Wrong ip address has been specified. {args[1]}")
        exit(-1)
    else:
        ipaddress = args[1]

    # UDP/IP communication instance
    connection = EtherCATMasterConnection(ipaddress, 34980)
    # SDO Information service instance
    master_config = MasterODSpecification(connection=connection)
    # ETG.1510 SDO update command generator
    etg1510 = ETG1510Profile(master_od=master_config)
    # As first, getting SDO specification with SDO information service.
    asyncio.run(etg1510.master_od.get_object_dictionary())
    # get whole sdo data on an asynchronous task.
    asyncio.run(get_etg1510_whole_data(etg1510))
    # get sdo data index 0xa001
    asyncio.run(get_etg1510_data(etg1510, 0xA001))
    # get sdo data cyclically
    asyncio.run(get_etg1510_data_frequently(etg1510))

This sample would work as below. These are part of output for whole entries.

$ python etg1510.py 192.168.2.254
{'0x1000': {'DeviceType': 0}}
{'0x1008': {'DeviceName': 'TwinCAT EtherCAT Master'}}
{'0x1009': {'HardwareVersion': '0'}}
{'0x100a': {'SoftwareVersion': '3.1 1737'}}
{'0x1018': {'NumberOfEntries': 4,
            'ProductCode': 65539,
            'RevisionNumber': 1737,
            'SerialNumber': 0,
            'VendorID': 2}}
{'0x8000': {'DeviceType': 0,
            'DiagHistoryObjectSupported': False,
            'FixedStationAddress': 1001,
            'Flags': 0,
            'LinkPreset': 17,
            'LinkStatus': 0,
            'MailboxInSize': 0,
            'MailboxOutSize': 0,
            'MailboxProtocolsSupported': 0,
            'Name': 'Term 1 (EK1100)',
            'NumberOfEntries': 37,
            'PortPhysics': 0,
            'ProductCode': 72100946,
            'RevisionNumber': 1114112,
            'SerialNumber': 0,
            'Type': 'EK1100',
            'VendorId': 2}}
{'0x8001': {'DeviceType': 0,
            'DiagHistoryObjectSupported': False,
            'FixedStationAddress': 1002,
            'Flags': 0,
            'LinkPreset': 17,
            'LinkStatus': 0,
            'MailboxInSize': 0,
            'MailboxOutSize': 0,
            'MailboxProtocolsSupported': 0,
            'Name': 'Term 2 (EL1012)',
            'NumberOfEntries': 37,
            'PortPhysics': 0,
            'ProductCode': 66334802,
            'RevisionNumber': 1048576,
            'SerialNumber': 0,
            'Type': 'EL1012',
            'VendorId': 2}}
              :
              :
{'0xa000': {'ALControl': 8,
            'ALStatus': 8,
            'ALStatusCode': 0,
            'AbnormalStateChangeCounter': 0,
            'CyclicWCErrorCounter': 0,
            'DisableAutomaticLinkControl': False,
            'FixedAddressConnPort': [0, 1002, 0, 0],
            'FrameErrorCounterPort': [0, 0, 0, 0],
            'LastProtocolError': 0,
            'LinkConnStatus': 50,
            'LinkControl': 240,
            'NewDiagMessageAvailable': False,
            'NumberOfEntries': 17,
            'SlaveNotPresentCounter': 7}}
{'0xa001': {'ALControl': 8,
            'ALStatus': 8,
            'ALStatusCode': 0,
            'AbnormalStateChangeCounter': 0,
            'CyclicWCErrorCounter': 1,
            'DisableAutomaticLinkControl': False,
            'FixedAddressConnPort': [1001, 1003, 0, 0],
            'FrameErrorCounterPort': [0, 0, 0, 0],
            'LastProtocolError': 0,
            'LinkConnStatus': 51,
            'LinkControl': 240,
            'NewDiagMessageAvailable': False,
            'NumberOfEntries': 17,
            'SlaveNotPresentCounter': 7}}
              :
              :
{'0xf002': {'NumberofEntries': 67,
            'ScanCommandRequest': '\x04\x06',
            'ScanCommandResponse': '',
            'ScanCommandStatus': 0}}
{'0xf020': {'ConfiguredAddress': [1001, 1002, ..., 0], 'NumberofSlaves': 10}}
{'0xf120': {'ACyclicFramesPerSecond': 0,
            'ACyclicLostFrames': 98826091,
            'CyclicFramesPerSecond': 0,
            'CyclicLostFrames': 66,
            'MasterState': 0,
            'NumberOfEntries': 2}}
{'0xf200': {'NumberOfEntries': 1, 'ResetDiagInfo': False}}

And especially diagnosis data part shows additional properties that are link status and status of state machine.

{'0xa001': {'ALControl': 8,
            'ALStatus': 8,
            'ALStatusCode': 0,
            'AbnormalStateChangeCounter': 0,
            'CyclicWCErrorCounter': 0,
            'DisableAutomaticLinkControl': False,
            'FixedAddressConnPort': [1001, 1003, 0, 0],
            'FrameErrorCounterPort': [0, 0, 0, 0],
            'LastProtocolError': 0,
            'LinkConnStatus': 51,
            'LinkControl': 240,
            'NewDiagMessageAvailable': False,
            'NumberOfEntries': 17,
            'SlaveNotPresentCounter': 2}}
{'PortStatus': [PortStatus(use_to_communication=True,
                           link_up=True,
                           loop_control=<LoopControl.Auto: 0>),
                PortStatus(use_to_communication=True,
                           link_up=True,
                           loop_control=<LoopControl.Auto: 0>),
                PortStatus(use_to_communication=False,
                           link_up=False,
                           loop_control=<LoopControl.Close: 3>),
                PortStatus(use_to_communication=False,
                           link_up=False,
                           loop_control=<LoopControl.Close: 3>)]}
{'ALStatusCode': <ALStausCode.NoError: ALStatusCodeDef(code=0, occurrence_timing='Any', transition_state='Current', reference='ETG.1000.6')>}
{'ALControl': <ALStatus.OP: 8>}
{'ALStatus': <ALStatus.OP: 8>}
{'Is Rejected?': False}
{'Is Updated?': False}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyetg1510-0.1.3.tar.gz (25.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyetg1510-0.1.3-py3-none-any.whl (31.1 kB view details)

Uploaded Python 3

File details

Details for the file pyetg1510-0.1.3.tar.gz.

File metadata

  • Download URL: pyetg1510-0.1.3.tar.gz
  • Upload date:
  • Size: 25.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.11.5 Windows/10

File hashes

Hashes for pyetg1510-0.1.3.tar.gz
Algorithm Hash digest
SHA256 67ba33b07cc05c5ab5159db46d5d81f86be4642c09e6d1cb203fbd615d61375d
MD5 f116efbc3afc6dbb213e9182aa65fc9a
BLAKE2b-256 6a9f1ce04f51a7ac5897530b08d17ff0aff8e15abbd3e9a272a831f850307822

See more details on using hashes here.

File details

Details for the file pyetg1510-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: pyetg1510-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 31.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.11.5 Windows/10

File hashes

Hashes for pyetg1510-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 97af1e731236b2ce9a4d7f2643dfb051c6d2900d6f2ae32dbbfa06e9044da05f
MD5 df5febfb4ab6abd4e46374461d457ea4
BLAKE2b-256 209f6a98140c13e8f728082eccce5dad63aa50a6518acb0a194bcfb1bb49655b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page