Skip to main content

A library to communicate with Omron NX and NJ PLC and motion controllers

Project description

aphyt

This is a library for communicating with industrial devices using Python.

Current development effort is to create Omron Ethernet/IP communications to NX and NJ controllers.

Communicating with Omron Sysmac Controllers Using Ethernet/IP

The current release of this software implements the core functionality of reading and writing numeric and Boolean variables to an Omron NX or NJ controller using symbolic names. The key method that goes beyond CIP type requests is update_variable_dictionary. This method uses an Ethernet/IP explicit connection to get the names and data type codes of all published variables, both system and user defined. This information is then used to allow the programmer to use Python based Boolean and numeric data types to write to variables, as well as properly format the data received when reading variables. The example code below demonstrates how to establish the explicit Ethernet/IP connection and then read and write variables to a test project in the NJ or NX controller. Currently Supported Data Types

BOOLEAN
SINT (1-byte signed binary)
INT (1-word signed binary)
DINT (2-word signed binary)
LINT (4-word signed binary)
USINT (1-byte unsigned binary)
UINT (1-word unsigned binary)
UDINT (2-word unsigned binary)
ULINT (4-word unsigned binary)
REAL 2-word floating point)
LREAL (4-word floating point)
STRING
CIP_BYTE = b'\xd1'  # (1-byte hexadecimal)
CIP_WORD = b'\xd2'  # (1-word hexadecimal)
CIP_DWORD = b'\xd3'  # (2-word hexadecimal)
CIP_TIME = b'\xdb'  # (8-byte data)
CIP_LWORD = b'\xd4'  # (4-word hexadecimal)
CIP_ABBREVIATED_STRUCT = b'\xa0'
CIP_STRUCT = b'\xa2'
CIP_ARRAY = b'\xa3'

Future Development

The plan is to support all CIP and Omron specific data types, including derived data types like arrays and structures. From there, development efforts will go to reading and writing to logical segments and supporting additional devices transparently.

Example Use

Installation

This package is on PyPI so the user can install using:

pip install aphyt

Getting Started

In order to use and explicit connection the programmer should import the n_series file from the eip module to give the program access to the classes to connect to the controller. The programmer should: instantiate an instance from the NSeriesEIP object, connect to the IP address of the controller, register a session and then update the variable dictionary.

The update variable dictionary method creates a dictionary that maps variable names to variable types so that the read_variable and write_variable methods can encode and decode data that is sent to and received from the controller, so the programmer can easily interact with controller data

from aphyt import omron

eip_instance = omron.n_series.NSeriesEIP()
eip_instance.connect_explicit('192.168.250.13')
eip_instance.register_session()
eip_instance.update_variable_dictionary()

reply = eip_instance.read_variable('TestBoolFalse')
print("TestBoolFalse: " + str(reply))
reply = eip_instance.write_variable('TestBoolFalse', True)
reply = eip_instance.read_variable('TestBoolFalse')
print("TestBoolFalse: " + str(reply))
reply = eip_instance.write_variable('TestBoolFalse', False)
reply = eip_instance.read_variable('TestBoolFalse')
print("TestBoolFalse: " + str(reply))

reply = eip_instance.read_variable('TestBoolTrue')
print("TestBoolTrue: " + str(reply))

reply = eip_instance.read_variable('TestInt1')
print("TestInt1: " + str(reply))
reply = eip_instance.write_variable('TestInt1', 2)
reply = eip_instance.read_variable('TestInt1')
print("TestInt1: " + str(reply))
reply = eip_instance.write_variable('TestInt1', 1)
reply = eip_instance.read_variable('TestInt1')
print("TestInt1: " + str(reply))

reply = eip_instance.read_variable('TestLREAL')
print("TestLREAL: " + str(reply))
reply = eip_instance.write_variable('TestLREAL', 63.12)
reply = eip_instance.read_variable('TestLREAL')
print("TestLREAL: " + str(reply))
reply = eip_instance.write_variable('TestLREAL', 3.4)
reply = eip_instance.read_variable('TestLREAL')
print("TestLREAL: " + str(reply))

tale_of_two_cities_string_1 = \
    'In England, there was scarcely an amount of order and protection to justify much national boasting. ' \
    'Daring burglaries by armed men, and highway robberies, took place in the capital itself every night; ' \
    'families were publicly cautioned not to go out of town without removing their furniture to upholsterers' \
    ' warehouses for security; the highwayman in the dark was a City tradesman in the light, and, being ' \
    'recognised and challenged by his fellow-tradesman whom he stopped in his character of \"the Captain,\" ' \
    'gallantly shot him through the head and rode away; the mail was waylaid by seven robbers, and the guard shot ' \
    'three ' \
    'dead, and then got shot dead himself by the other four, \"in consequence of the failure of his ammunition:\" ' \
    'after which the mail was robbed in peace; that magnificent potentate, the Lord Mayor of London, was made to ' \
    'stand and deliver on Turnham Green, by one highwayman, who despoiled the illustrious creature in sight of ' \
    'all his retinue; prisoners in London gaols fought battles with their turnkeys, and the majesty of the law ' \
    'fired blunderbusses in among them, loaded with rounds of shot and ball; thieves snipped off diamond crosses ' \
    'from the necks of noble lords at Court drawing-rooms; musketeers went into St. Giles\'s, to search for ' \
    'contraband goods, and the mob fired on the musketeers, and the musketeers fired on the mob, and nobody thought ' \
    'any of these occurrences much out of the common way. In the midst of them, the hangman, ever busy and ' \
    'ever worse than useless, was in constant requisition; now, stringing up long rows of miscellaneous criminals; ' \
    'now, hanging a housebreaker on Saturday who had been taken on Tuesday; now, burning people in the hand ' \
    'at Newgate by the dozen, and now burning pamphlets at the door of Westminster Hall; to-day, taking the ' \
    'life of an atrocious murderer, and to-morrow of a wretched pilferer who had robbed a farmer\'s boy of sixpence.'
tale_of_two_cities_string_2 = \
    'Two other passengers, besides the one, were plodding up the hill by the side of the mail. All three were ' \
    'wrapped to the cheekbones and over the ears, and wore jack-boots. Not one of the three could have said, ' \
    'from anything he saw, what either of the other two was like; and each was hidden under almost as many ' \
    'wrappers from the eyes of the mind, as from the eyes of the body, of his two companions. In those days, ' \
    'travellers were very shy of being confidential on a short notice, for anybody on the road might be a robber ' \
    'or in league with robbers. As to the latter, when every posting-house and ale-house could produce ' \
    'somebody in \"the Captain\'s\" pay, ranging from the landlord to the lowest stable non-descript, it was ' \
    'the likeliest thing upon the cards. So the guard of the Dover mail thought to himself, that Friday night ' \
    'in November, one thousand seven hundred and seventy-five, lumbering up Shooter\'s Hill, as he stood on his ' \
    'own particular perch behind the mail, beating his feet, and keeping an eye and a hand on the arm-chest before ' \
    'him, where a loaded blunderbuss lay at the top of six or eight loaded horse-pistols, deposited on a substratum ' \
    'of cutlass.'

reply = eip_instance.read_variable('TestString_Copy')
print(reply)
eip_instance.write_variable('TestString_Copy', tale_of_two_cities_string_2)
reply = eip_instance.read_variable('TestString_Copy')
print(reply)
eip_instance.write_variable('TestString_Copy', tale_of_two_cities_string_1)
reply = eip_instance.read_variable('TestString_Copy')
print(reply)

reply = eip_instance.read_variable('ArrayOfStuff')
print(reply)
reply[4] = 17.3
# print(reply)
eip_instance.write_variable('ArrayOfStuff', reply)
reply = eip_instance.read_variable('ArrayOfStuff')
print(reply)
reply[4] = 0.0
eip_instance.write_variable('ArrayOfStuff', reply)
reply = eip_instance.read_variable('ArrayOfStuff')
print(reply)
reply = eip_instance.read_variable('ThreeDimLrealArray')
print(reply)

reply = eip_instance.read_variable('Axis5Segment')
print(reply)

reply = eip_instance.read_variable('TestStruct1')
print(reply)

reply['Bool2'] = False
reply = eip_instance.write_variable('TestStruct1', reply)
reply = eip_instance.read_variable('TestStruct1')
print(reply)

reply['Bool2'] = True
reply = eip_instance.write_variable('TestStruct1', reply)
reply = eip_instance.read_variable('TestStruct1')
print(reply)

reply['LintMember'] = 7000
reply = eip_instance.write_variable('TestStruct1', reply)
reply = eip_instance.read_variable('TestStruct1')
print(reply)

reply['LintMember'] = 14000
reply = eip_instance.write_variable('TestStruct1', reply)
reply = eip_instance.read_variable('TestStruct1')
print(reply)

reply = eip_instance.read_variable('PartArray')
print(reply)
reply[2]['part_name'] = 'ThirdItem'
reply = eip_instance.write_variable('PartArray', reply)
reply = eip_instance.read_variable('PartArray')
print(reply)
reply[2]['part_name'] = 'BackItem'
reply = eip_instance.write_variable('PartArray', reply)
reply = eip_instance.read_variable('PartArray')
print(reply)
# Demonstrate getitem
print(reply[0]['part_name'])

reply = eip_instance.read_variable('_CurrentTime')
print(reply)

eip_instance.close_explicit()

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

aphyt-0.1.7.tar.gz (28.0 kB view details)

Uploaded Source

Built Distribution

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

aphyt-0.1.7-py3-none-any.whl (30.4 kB view details)

Uploaded Python 3

File details

Details for the file aphyt-0.1.7.tar.gz.

File metadata

  • Download URL: aphyt-0.1.7.tar.gz
  • Upload date:
  • Size: 28.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.1 setuptools/50.3.0 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.8.5

File hashes

Hashes for aphyt-0.1.7.tar.gz
Algorithm Hash digest
SHA256 753c4e4db3e0f520a48a5de24dff501bde08f212851b4634092b94bb390a99b7
MD5 4453c7b3ffd23a866cf71e7eb9f9cb92
BLAKE2b-256 13fb1ff2a1bd1bc685510e02e83d5bb003dc6f6579103f50e2b1288a6b621e92

See more details on using hashes here.

File details

Details for the file aphyt-0.1.7-py3-none-any.whl.

File metadata

  • Download URL: aphyt-0.1.7-py3-none-any.whl
  • Upload date:
  • Size: 30.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.1 setuptools/50.3.0 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.8.5

File hashes

Hashes for aphyt-0.1.7-py3-none-any.whl
Algorithm Hash digest
SHA256 1090c47e04c262dd409d49f1dcf008e65b7800bbf38a8c16d9ed6d67ac3216b6
MD5 2f0955f82b4a9d94697abdaa221580d4
BLAKE2b-256 945fd06ff04c556feb5c28e56ac529ad0296204b5fdcea7521b894b00cdfb12d

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