• 正文
    • 一、關于CIPDriver模塊
    • 二、繼續(xù)實驗
  • 相關推薦
申請入駐 產(chǎn)業(yè)圖譜

python實現(xiàn)Ethernet/IP協(xié)議的客戶端(三)

2024/11/25
2956
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

Ethernet/IP是一種工業(yè)自動化領域中常用的網(wǎng)絡通信協(xié)議,它是基于標準以太網(wǎng)技術的應用層協(xié)議。作為工業(yè)領域的通信協(xié)議之一,Ethernet/IP 提供了一種在工業(yè)自動化設備之間實現(xiàn)通信和數(shù)據(jù)交換的標準化方法。python要實現(xiàn)Ethernet/IP的客戶端,可以采用pycomm3模塊,但不一定是pycomm3,其中原委咋們慢慢聊,本文為第三篇。

一、關于CIPDriver模塊

1、官方例子

Generic Messaging - pycomm3 1.2.14 documentation

在官方例子中,出現(xiàn)率最高的方法是 generic_message ,我們再去看看他的API。

2、API

CIPDriver API - pycomm3 1.2.14 documentation

在這個文檔中,我們驚訝地發(fā)現(xiàn)他的主要方法也只是generic_message,這讓人感覺不太可能實現(xiàn)第一篇文章的交互。

3、還是先用吧

明知這個類大概率實現(xiàn)不了,為什么還要繼續(xù)呢?

我們在實現(xiàn)一個協(xié)議時,最起碼先了解這個協(xié)議吧?在第一篇文章中,我們了解的情況是閱讀了一些官方文檔,也了解了EDS文件,但沒有一個具體的實驗。因此,繼續(xù)是有必要的,至少能了解協(xié)議本身。

4、generic_message方法

對于官方例子,我們先結合源碼描述簡單分析:

(1)源碼描述

    def generic_message(
        self,
        service: Union[int, bytes],
        class_code: Union[int, bytes],
        instance: Union[int, bytes],
        attribute: Union[int, bytes] = b"",
        request_data: Any = b"",
        data_type: Optional[Union[Type[DataType], DataType]] = None,
        name: str = "generic",
        connected: bool = True,
        unconnected_send: bool = False,
        route_path: Union[bool, Sequence[CIPSegment], bytes, str] = True,
        **kwargs,
    ) -> Tag:
        """
        Perform a generic CIP message.  Similar to how MSG instructions work in Logix.

        :param service: service code for the request (single byte)
        :param class_code: request object class ID
        :param instance: ID for an instance of the class
                         If set with 0, request class attributes.
        :param attribute: (optional) attribute ID for the service/class/instance
        :param request_data: (optional) any additional data required for the request.
        :param data_type: a ``DataType`` class that will be used to decode the response, None to return just bytes
        :param name:  return ``Tag.tag`` value, arbitrary but can be used for tracking returned Tags
        :param connected: ``True`` if service required a CIP connection (forward open), ``False`` to use UCMM
        :param unconnected_send: (Unconnected Only) wrap service in an UnconnectedSend service
        :param route_path: (Unconnected Only) ``True`` to use current connection route to destination, ``False`` to ignore,
                           Or provide a path string, list of segments to be encoded as a PADDED_EPATH, or
                           an already encoded path.
        :return: a Tag with the result of the request. (Tag.value for writes will be the request_data)
        """

(2)簡單分析

官方文檔直接給了一個函數(shù),我做了一些引入的補充,即“from pycomm3 import CIPDriver, Services, INT” :

from pycomm3 import CIPDriver, Services, INT

def read_pf525_parameter():
    drive_path = '10.10.10.100/bp/1/enet/192.168.1.55'

    with CIPDriver(drive_path) as drive:
        param = drive.generic_message(
            service=Services.get_attribute_single,
            class_code=b'x93',
            instance=41,  # Parameter 41 = Accel Time
            attribute=b'x09',
            data_type=INT,
            connected=False,
            unconnected_send=True,
            route_path=True,
            name='pf525_param'
        )
        print(param)

對于? ? drive_path = '10.10.10.100/bp/1/enet/192.168.1.55' 這個語句,再結合上次的實驗,我猜測EIP設備是10.10.10.100,并且該EIP設備是有一些子模塊的,192.168.1.55便是內(nèi)部的子模塊地址。中間的/bp/1/enet則是按照EIP協(xié)議規(guī)定的路徑。

在使用 with 語句創(chuàng)建了一個 CIPDriver 的實例(即自動調(diào)用了open()方法),確保在代碼塊結束時正確關閉連接后,接著調(diào)用了generic_message方法發(fā)送了一個通用的消息。具體參數(shù)如下:

  • service=Services.get_attribute_single: 使用 EtherNet/IP 協(xié)議中的 get_attribute_single 服務。
  • class_code=b'x93': 類別代碼,可能是特定設備或對象類型的標識。
  • instance=41: 代表要訪問的具體實例,這里是 Parameter 41。
  • attribute=b'x09': 屬性標識,可能代表具體要獲取的信息的類型。
  • data_type=INT: 數(shù)據(jù)類型,這里是整數(shù)。
  • connected=False: 表示使用不連接的方式發(fā)送消息。
  • unconnected_send=True: 允許未連接發(fā)送,可能用于廣播或多播。
  • route_path=True: 表示要使用路由路徑(如果需要)。
  • name='pf525_param': 為此消息指定了一個名稱,這個名稱在返回的結果中可以用于標識。

好了,通過上述解釋其實還有很多不理解的地方,我們繼續(xù)實驗來進一步了解。

二、繼續(xù)實驗

1、請求看看

修改代碼讓其請求成功,提示如下:

pf525_param, None, INT, IOI syntax error. A syntax error was detected decoding the Request Path (see extended status) - Extended status out of memory ?(04, 00)

表明沒有異常,只是服務器沒有這些擴展狀態(tài),說明我們請求的資源不存在。

from pycomm3 import CIPDriver, Services, INT

def read_pf525_parameter():
    drive_path = '192.168.1.189'

    with CIPDriver(drive_path) as drive:
        param = drive.generic_message(
            service=Services.get_attribute_single,
            class_code=b'x93',
            instance=41,
            attribute=b'x09',
            data_type=INT,
            connected=False,
            unconnected_send=True,
            route_path=True,
            name='pf525_param'
        )
        print(param)

read_pf525_parameter()

查看了報文依舊在報路徑錯誤。

我們對比一下正常的請求,我們的請求缺失了請求服務列表這一步,打開路徑時是以不連接進行打開的,因此差異很大。

2、怎么辦呢

莫慌,問題總會得到解決的,而且現(xiàn)在我們的思路很清晰,即我們的請求有問題,下一步就是不斷實驗就好?,F(xiàn)在我們應該具備一系列的進行實驗的素質(zhì),這些素質(zhì)有助于確保實驗的成功進行并獲得可靠的結果。以下是一些進行實驗時應具備的素質(zhì):

好奇心: 具備對未知事物的好奇心,愿意去探索和發(fā)現(xiàn)新知識。

耐心: 實驗過程中可能需要耐心等待結果或進行多次試驗,特別是在研究型實驗中。

精確性: 具備準確記錄實驗數(shù)據(jù)的能力,以確保實驗結果的可信度。

邏輯思維: 能夠理清實驗的步驟和邏輯,分析實驗結果并得出結論。

實驗設計能力: 能夠設計合理的實驗方案,考慮到實驗的目的、變量和控制措施。

安全意識: 遵守實驗室安全規(guī)定,正確使用實驗設備,確保實驗過程中的安全。

團隊合作: 在團隊中合作順利,有時實驗需要多人協(xié)作完成。

問題解決能力: 遇到實驗中的問題時能夠迅速分析并找到解決方案。

記錄與報告: 能夠準確地記錄實驗步驟和結果,并能夠撰寫清晰的實驗報告。

批判性思維: 能夠審慎評估實驗的方法和結果,對實驗中的偏差和誤差有清晰的認識。

耐受失?。?/strong> 實驗中可能會遇到失敗或意外,具備面對挫折的耐受力。

道德責任感: 遵守科學研究的倫理規(guī)范,保護實驗對象和參與者的權益。

這些素質(zhì)有助于建立一個科學、安全、可靠的實驗環(huán)境,確保實驗的有效進行和獲得有意義的結果。

相關推薦