工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 産業技術

gRPC Python – プロセス データの読み取りと書き込み

この記事では、gRPC を利用した AXC F 3152 を使用して Python で簡単なプロセス データにアクセスして書き込む方法について説明します。 (https://www.plcnext.help/te/Service_Components/gRPC_Introduction.htm)

前提条件

まず、必要なファイルを PLC の外部 (Windows マシンなど) で準備する必要があります。

<オール>
  • Python 3.9 をインストールします (3.10 ではエラーが発生する場合があります)
  • 必要な Python パッケージをインストールして、.proto ファイルからコードを生成します:pip install grpcio-tools==1.36.1
  • .proto ファイルを含むリポジトリを https://github.com/PLCnext/gRPC からダウンロードして解凍します
  • .proto ファイルから _pb2.py と _pb2_grpc.py を生成

    次に、提供された .proto ファイルから必要な python ファイルを生成する必要があります。後者は次のフォルダーにあります:gRPC-master/protobuf。

    このコードを使用して、フォルダー gRPC-master に Python スクリプトを作成します (例:generate_grpc.py)。スクリプト

    <オール>
  • 必要なファイルを生成し、gRPC-master/pxc_grpc に配置します
  • インポート パスを調整する
  • 
    import glob
    import os
    from pathlib import Path
    
    # create the output directory
    Path('pxc_grpc').mkdir(parents=True, exist_ok=True)
    
    grpc_command_base = 'python -m grpc_tools.protoc -I./protobuf --python_out=pxc_grpc --grpc_python_out=pxc_grpc '
    
    import_paths = set()
    
    # generate the *_pb2.py and *_pb2_grpc.py files
    for filename in glob.iglob('./protobuf/**', recursive=True):
    
        if filename.endswith('.proto'):
            
            # store the import path
            path_parts = filename.split(os.sep)
            import_paths.add('.'.join(path_parts[1:-1]))
    
            grpc_command = ''.join([grpc_command_base, os.path.join('.', os.path.relpath(filename))])
            stream = os.popen(grpc_command)
            output = stream.read()
            if output != '':
                print(''.join(['error/info for file ', os.path.relpath(filename), ' - ', output]))
    
    
    # get the python files in the base directory
    base_pys = set()
    
    for (dirpath, dirnames, filenames) in os.walk('./pxc_grpc'):
        for f in filenames:
            base_pys.add(f.split('.py')[0])
        break
    
    # reformat the stored paths to adapt the import statements
    try:
        import_paths.remove('')
    except:
        pass
    
    import_paths = list(import_paths)
    import_paths.sort(key=len)
    import_paths.reverse()
    
    # adapt the imports
    for filename in glob.iglob('./pxc_grpc/**', recursive=True):
    
        if filename.endswith('.py'):
    
            new_lines = []
    
            with open(filename, 'r') as file:
                lines = file.readlines()
                for line in lines:
                    if line.startswith('from'):
                        for import_path in import_paths:
                            if import_path in line:
                                line = line.replace(import_path, ''.join(['pxc_grpc.', import_path]), 1)
                                break
                    elif line.startswith('import'):
                        parts = line.split()
                        if parts[1] in base_pys:
                            line = line.replace('import', 'from pxc_grpc import')
                    
                    new_lines.append(line)
    
            with open(filename, 'w') as file:
                file.write(''.join(new_lines))
    
    

    シェルを開き、次のスクリプトを実行します:pyton generate_grpc.py

    PLCnext デモ プロジェクトを作成する

    示されているプロジェクトは、gRPC インターフェイスが GDS と対話する方法のみを示している必要があります。代わりに、既存のプロジェクトを自由に使用してください。個々のプロジェクトでは、それに応じて次の Python スクリプトのポート名を編集する必要があります (例:Arp.Plc.Eclr/MainInstance.strInput)。 .

    PLC の準備

    pip をインストールして Python パッケージを管理します:

    <オール>
  • AXC F 3152 コントローラーをインターネットに接続します。
  • コマンド curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py を入力します。
  • 次に、コマンド python3 get-pip.py を入力します。
  • 必要なパッケージをインストールします:pip install grpcio protobuf==3.20.0

    プロジェクト ディレクトリ (/opt/plcnext/projects/) にフォルダー「grpc_test」を作成します。

    作成された Python ファイルを含む「pxc_grpc」フォルダーを、WinSCP などを使用して「grpc_test」にコピーします。

    「grpc_test.py」という名前の「grpc_test」フォルダーに Python スクリプトを作成し、次のコードを挿入します。

    
    import grpc
    from pxc_grpc.Plc.Gds.IDataAccessService_pb2 import IDataAccessServiceReadSingleRequest, \
        IDataAccessServiceReadRequest, IDataAccessServiceWriteSingleRequest, IDataAccessServiceWriteRequest
    from pxc_grpc.Plc.Gds.IDataAccessService_pb2_grpc import IDataAccessServiceStub
    from pxc_grpc.Plc.Gds.WriteItem_pb2 import WriteItem
    
    
    def write_single_string(stub, port_name, value):
        
        single_write_request = IDataAccessServiceWriteSingleRequest()
        single_write_request.data.PortName = port_name
        single_write_request.data.Value.TypeCode = 19
        single_write_request.data.Value.StringValue = value
    
        return stub.WriteSingle(single_write_request)
    
    
    def write_single_int(stub, port_name, value):
        
        single_write_request = IDataAccessServiceWriteSingleRequest()
        single_write_request.data.PortName = port_name
        single_write_request.data.Value.TypeCode = 6
        single_write_request.data.Value.Int16Value = value
    
        return stub.WriteSingle(single_write_request)
    
    
    def write_multiple_values(stub):
    
        write_request = IDataAccessServiceWriteRequest()
    
        wi1 = WriteItem()
        wi1.PortName = 'Arp.Plc.Eclr/MainInstance.strInput'
        wi1.Value.StringValue = "test1"
        wi1.Value.TypeCode = 19
        
        wi2 = WriteItem()
        wi2.PortName = 'Arp.Plc.Eclr/MainInstance.strInput2'
        wi2.Value.StringValue = "test2"
        wi2.Value.TypeCode = 19
    
        # add multiple WriteItems at once
        write_request.data.extend([wi1, wi2])
    
        # add WriteItems separately
        # response1.data.append(wi1)
        # response1.data.append(wi2)
    
        return stub.Write(write_request)
    
    
    def read_single_value(stub, port_name):
    
        single_read_request = IDataAccessServiceReadSingleRequest()
        single_read_request.portName=port_name
    
        return stub.ReadSingle(single_read_request)
    
    
    def read_multiple_values(stub, port_names):
    
        read_request = IDataAccessServiceReadRequest()
        read_request.portNames.extend(port_names)
    
        return stub.Read(read_request)
    
    
    if __name__ == "__main__":
       
        # create channel and stub
        channel = grpc.insecure_channel('unix:/run/plcnext/grpc.sock')
        stub = IDataAccessServiceStub(channel)
    
        print(write_single_string(stub, 'Arp.Plc.Eclr/MainInstance.strInput', 'test123'))
        print(write_single_int(stub, 'Arp.Plc.Eclr/MainInstance.iInput', 18))
    
        print(write_multiple_values(stub))
    
        r = read_single_value(stub, 'Arp.Plc.Eclr/MainInstance.strInput')
        print(r)
        print(r._ReturnValue.Value.TypeCode)
        print(r._ReturnValue.Value.StringValue)
    
        r = read_multiple_values(stub, ['Arp.Plc.Eclr/MainInstance.iInput', 'Arp.Plc.Eclr/MainInstance.strInput'])
        for value in r._ReturnValue:
            print(value, value.Value.TypeCode)
    
    
    

    PLC を PLCnext Engineer に接続し、プロジェクトをダウンロードして、ライブ ビューを開始します。

    サンプルを実行

    例を開始します。 ssh 経由で PLC にログインし、「grpc_test」に移動してから、Python スクリプトを開始します。

    <オール>
  • cd projects/grpc_test/
  • python3 grpc_test.py
  • gRPC により、GDS 変数とのやり取りが可能になります。

    データ型

    変数を読み書きするには、データ型が必要です (例:wi1.Value.TypeCode = 19)。 .型は生成されたファイル gRPC-master/pxc_grpc/ArpTypes_pb2.py に記述されています 242行目から:

    CT_None = 0
    CT_End = 0
    CT_Void = 1
    CT_Boolean = 2
    CT_Char = 3
    CT_Int8 = 4
    CT_Uint8 = 5
    CT_Int16 = 6
    CT_Uint16 = 7
    CT_Int32 = 8
    CT_Uint32 = 9
    CT_Int64 = 10
    CT_Uint64 = 11
    CT_Real32 = 12
    CT_Real64 = 13
    CT_Struct = 18
    CT_String = 19
    CT_Utf8String = 19
    CT_Array = 20
    CT_DateTime = 23
    CT_Version = 24
    CT_Guid = 25
    CT_AnsiString = 26
    CT_Object = 28
    CT_Utf16String = 30
    CT_Stream = 34
    CT_Enumerator = 35
    CT_SecureString = 36
    CT_Enum = 37
    CT_Dictionary = 38
    CT_SecurityToken = 39
    CT_Exception = 40
    CT_IecTime = 41
    CT_IecTime64 = 42
    CT_IecDate = 43
    CT_IecDate64 = 44
    CT_IecDateTime = 45
    CT_IecDateTime64 = 46
    CT_IecTimeOfDay = 47
    CT_IecTimeOfDay64 = 48
    

    対応する値変数 (例:r._ReturnValue.Value.StringValue) 、同じファイルの 365 行目から見つけることができます (例:BoolValue)。 、 Int8ValueStringValue .


    産業技術

    1. デジタルメモリの用語と概念
    2. Apacer:世界中で発売されたCV110-SDおよびCV110-MSDカード
    3. Apacer:読み取り/書き込み速度が560および520MB /秒の産業用グレードのSV250SSDシリーズ
    4. ビッグデータを理解する方法:RTUとプロセス制御アプリケーション
    5. フライス盤とは何ですか?-定義、プロセス、および操作
    6. 掘削とは何ですか?-定義、プロセス、およびヒント
    7. 粉末冶金とは何ですか?-定義とプロセス
    8. ブローチとは何ですか?-プロセス、作業、およびタイプ
    9. 化学機械加工とは何ですか?-作業、およびプロセス
    10. 超音波加工とは何ですか?-作業とプロセス
    11. スプレー溶接とは何ですか?-プロセスと技術