2015-07-16 9 views
3

Недавно я приобрел линейный привод ACS (Tolomatic Stepper), который я пытаюсь отправить данные из приложения Python. Само устройство связывается с использованием протокола Ethernet/IP.Чтение/запись значений с использованием Ethernet/IP

Я установил библиотеку cpppo через pip. Когда я делаю команду в попытке прочитать состояние устройства, я возвращаю None. Изучая связь с Wireshark, я вижу, что она выглядит так, как будто она выполняется правильно, однако я замечаю ответ от устройства, указывающий: Сервис не поддерживается.

Пример кода я использую, чтобы проверить чтение «Вход в сборе»:

from cpppo.server.enip import client 

HOST = "192.168.1.100" 
TAGS = ["@4/100/3"] 

with client.connector(host=HOST) as conn: 
    for index, descr, op, reply, status, value in conn.synchronous(
      operations=client.parse_operations(TAGS)): 
     print(": %20s: %s" % (descr, value)) 

Я ожидаю, чтобы получить «входной узел» читать, но это не кажется, работает таким образом. Я предполагаю, что у меня что-то отсутствует, так как это первое время, когда я пытался подключиться к сети Ethernet/IP.

Я не уверен, как действовать или что мне не хватает в отношении Ethernet/IP, которые могут сделать эту работу корректной.

ответ

5

Clutton. - Я автор модуля cpppo ,

Извините за задержанный ответ. Недавно мы реализовали возможность общения с простыми (нерукавирующими) CIP-устройствами. Контроллеры ControlLogix/CompactLogix реализуют расширенный набор возможностей EtherNet/IP CIP, чего нет у большинства простых CIP-устройств. Кроме того, они, как правило, также не выполняют запрос * Readix * Logix «Read Tag»; вам нужно бороться с базовыми запросами «Получить атрибут Single/All», которые просто возвращают необработанные 8-битные данные. Это зависит от вас, чтобы вернуть его обратно в CIP REAL, INT, DINT и т. Д.

Чтобы связаться с вашим линейным приводом, вам необходимо отключить эти расширенные инкапсуляции и использовать запросы «Получить атрибут один» , Это делается путем указания пустого пути route_path = [] и send_path = '' при анализе ваших операций и использования атрибутов атрибутов cpppo.server.enip.getattr (вместо parse_operations cpppo.server.enip.client):

from cpppo.server.enip import client 
from cpppo.server.enip.getattr import attribute_operations 

HOST = "192.168.1.100" 
TAGS = ["@4/100/3"] 

with client.connector(host=HOST) as conn: 
    for index, descr, op, reply, status, value in conn.synchronous(
     operations=attribute_operations(
      TAGS, route_path=[], send_path='')): 
     print(": %20s: %s" % (descr, value)) 

Это должно сделать трюк!

Мы находимся в процессе развертывания основного обновления модуля cpppo, поэтому клонируем https://github.com/pjkundert/cpppo.git Git repo и проверяем ветку идентификатора списка функций, чтобы получить ранний доступ к гораздо лучшим API для доступа к необработанным данным из эти простые устройства для тестирования. Вы будете иметь возможность использовать cpppo для преобразования исходных данных в CIP реалов, вместо того, чтобы сделать это самостоятельно ...

...

С Cpppo> = 3.9.0, теперь вы можете использовать гораздо более мощные интерфейсы cpppo.server.enip.get_attribute 'proxy' и 'proxy_simple' для маршрутизации CIP-устройств (например, ControlLogix, Compactlogix) и нерушимых «простых» CIP-устройств (например, MicroLogix, PowerFlex и т. д.):

$ python 
>>> from cpppo.server.enip.get_attribute import proxy_simple 
>>> product_name, = proxy_simple('10.0.1.2').read([('@1/1/7','SSTRING')]) 
>>> product_name 
[u'1756-L61/C LOGIX5561'] 

Если вы хотите регулярно обновлять, используйте cpppo.server.enip.Опрос:

import logging 
import sys 
import time 
import threading 

from cpppo.server.enip import poll 
from cpppo.server.enip.get_attribute import proxy_simple as device 
params     = [('@1/1/1','INT'),('@1/1/7','SSTRING')] 

# If you have an A-B PowerFlex, try: 
# from cpppo.server.enip.ab import powerflex_750_series as device 
# parms     = [ "Motor Velocity", "Output Current" ] 

hostname    = '10.0.1.2' 
values     = {} # { <parameter>: <value>, ... } 
poller     = threading.Thread(
    target=poll.poll, args=(device,), kwargs={ 
     'address':  (hostname, 44818), 
     'cycle':  1.0, 
     'timeout':  0.5, 
     'process':  lambda par,val: values.update({ par: val }), 
     'params':  params, 
    }) 
poller.daemon   = True 
poller.start() 

# Monitor the values dict (updated in another Thread) 
while True: 
    while values: 
     logging.warning("%16s == %r", *values.popitem()) 
    time.sleep(.1) 

И, Voila! Теперь у вас есть регулярное обновление имен параметров и значений в вашем dict. См. Примеры в cpppo/server/enip/poll_example * .py для получения дополнительной информации, например, о том, как сообщать о сбоях, контролировать экспоненциальное отключение повторных попыток подключения и т. Д.

Недавно выпущена версия 3.9.5, которая имеет поддержку для записи в теги и атрибуты CIP, используя прокси-сервер cpppo.server.enip.get_attribute и прокси-прокси API. См. Cpppo/server/enip/poll_example_many_with_write.py

+0

Это похоже на работу, спасибо. – clutton

+0

Можно ли использовать proxy_simple для записи одного атрибута? – JPelletier

+1

@JPelletier Я пришел сюда, ища тот же ответ. Похоже, что no, 'proxy_simple' (и' proxy') не выбрасывает исключение. Тем не менее, я успешно получил запись атрибутов, работающих с использованием 'connector' и' attribute_operations', как в первом примере. Кажется, что записи ограничены типом данных USINT, что я могу сказать. – Rich

0

надеюсь, что это очевидно, но доступ к HOST = «192.168.1.100» будет возможно только из системы, расположенной в подсети 192.168.1 *

+1

Связь с устройством происходит правильно, используя этот адрес. Я настраиваю тестовую среду специально для этой цели с «правильными» адресами. – clutton