PLCnext Control gRPCサーバー用C#クライアントの作成:ステップバイステップガイド
ファームウェアバージョン2022.0 LTSでは、AXC F 1152およびAXC F 2152デバイスにgRPCサーバーが導入されました。このgRPCサーバーは、クライアントアプリケーションがPLCnext Controlデバイス上のRSCサービスにアクセスするための手段を提供します。クライアントアプリケーションは:
- gRPCをサポートする任意の言語で記述可能
- どこでも実行可能 - PLCnext Controlデバイス上でローカルに、またはリモートマシン上で*
- OCIコンテナでホスト可能
(* リモートアクセスはファームウェアバージョン2022.3から利用可能)
PLCnext ControlデバイスのgRPCサーバーに関する一般的な情報は、PLCnext Info Centerで確認できます。
この記事では、PLCnext Controlデバイス上で実行されるシンプルなC# gRPCクライアントアプリケーションの作成方法を説明します。
前提条件
以下の手順では以下を使用します:
- ファームウェアバージョン2022.0.3 LTS以降を実行するAXC F 2152
- PLCnext Engineerバージョン2022.0.1 LTS以降
- Visual Studio 2019(任意のエディション)
- このメーカーズブログ記事で紹介されている概念:シンプルなPLCnextコンソールアプリケーションをC#で作成する方法
- PLCnext/gRPC GithubリポジトリのprotobufディレクトリにあるgRPCサーバー用のProtobuf定義ファイル
- Device Status RSCサービス
- Data Access RSCサービス
手順
1. Webベースの管理ページを使用して、GRPC LOCAL SERVICEという名前のサービスが有効になっていることを確認します。
2. ターゲットデバイス向けの新しいPLCnext Engineerプロジェクトを作成します。このプロジェクトには以下が必要です:
- AI1という名前のOUTポート変数(型:INT)を持つプログラム
- そのプログラムのインスタンス(MainInstance1)
3. PLCnext Engineerプロジェクトをターゲットデバイスに送信します。
4. Visual Studioで、以前のメーカーズブログ記事の手順1〜3に従って、空のC#コンソールアプリケーションを作成します。
5. プロジェクトのプロパティウィンドウで、プロジェクトのターゲットフレームワークを「.NET 5.0」に設定します。
6. ソリューションエクスプローラーでソリューションを右クリックし、「ソリューションのNuGetパッケージの管理...」を選択し、以下のNuGetパッケージをインストールします:
- Grpc.Tools
- Grpc.Net.Client
- Google.Protobuf
7. Protobuf定義ファイルを含むprotobufフォルダをプロジェクトのソースフォルダにコピーします。Protobufは、gRPCサービスを記述するために使用されるインターフェース定義言語(IDL)です。
8. プロジェクト設定ファイルで、プロジェクトで使用するサービスの.protoファイルへの参照を追加します。プロジェクト設定のItemGroupセクションは次のようになります:
9. プロジェクトの.csファイルの内容を以下のコードで置き換えます(名前空間名は変更が必要な場合があります):
using System; using System.Net; using System.Net.Http; using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; using System.IO; using Grpc.Net.Client; using Arp.Device.Interface.Services.Grpc; using Arp.Plc.Gds.Services.Grpc; namespace ConsoleApp1 { class Program { static void Main() { // Unix Domain Socketへの接続コードは以下から: // https://docs.microsoft.com/en-us/aspnet/core/grpc/interprocess?view=aspnetcore-6.0 var udsEndPoint = new UnixDomainSocketEndPoint("/run/plcnext/grpc.sock"); var connectionFactory = new UnixDomainSocketConnectionFactory(udsEndPoint); var socketsHttpHandler = new SocketsHttpHandler { ConnectCallback = connectionFactory.ConnectAsync }; // PLCnextのUnixソケットへのgRPCチャネルを作成 using var channel = GrpcChannel.ForAddress("https://localhost", new GrpcChannelOptions { HttpHandler = socketsHttpHandler }); // そのチャネル上でDevice Status ServiceのgRPCクライアントを作成 var grpc_status_client = new IDeviceStatusService.IDeviceStatusServiceClient(channel); // そのチャネル上でData Access ServiceのgRPCクライアントを作成 var grpc_data_client = new IDataAccessService.IDataAccessServiceClient(channel); // Device Status Serviceから取得するアイテムを作成 // アイテム識別子はPLCnext Info Centerに記載: // https://www.plcnext.help/te/Service_Components/Remote_Service_Calls_RSC/RSC_device_interface_services.htm#IDeviceStatusService var item = new IDeviceStatusServiceGetItemRequest(); item.Identifier = "Status.Board.Temperature.Centigrade"; // Data Access Serviceから取得する変数を作成 var data = new IDataAccessServiceReadSingleRequest(); data.PortName = "Arp.Plc.Eclr/MainInstance1.AI1"; // 応答変数 IDeviceStatusServiceGetItemResponse grpc_status_response; IDataAccessServiceReadSingleResponse grpc_data_response; // 無限ループ while (true) { // Device Status Serviceからアイテムを要求 grpc_status_response = grpc_status_client.GetItem(item); // Data Access Serviceからデータを要求 grpc_data_response = grpc_data_client.ReadSingle(data); // 結果を報告 var temperature = grpc_status_response.ReturnValue.Int8Value; var ai1 = grpc_data_response.ReturnValue.Value.Int16Value; Console.WriteLine("Board Temperature = " + temperature + "°C"); Console.WriteLine("MainInstance1.AI1 = " + ai1); // 1秒待機 Thread.Sleep(1000); } } } public class UnixDomainSocketConnectionFactory { private readonly EndPoint _endPoint; public UnixDomainSocketConnectionFactory(EndPoint endPoint) { _endPoint = endPoint; } public async ValueTask<Stream> ConnectAsync(SocketsHttpConnectionContext _, CancellationToken cancellationToken = default) { var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified); try { await socket.ConnectAsync(_endPoint, cancellationToken).ConfigureAwait(false); return new NetworkStream(socket, true); } catch { socket.Dispose(); throw; } } }
10. ソリューションエクスプローラーでソリューションを右クリックし、ターミナルを開きます。
11. ターミナルで以下のコマンドを実行します:
dotnet build ConsoleApp1.csproj dotnet publish -c RELEASE -r linux-arm .\ConsoleApp1.csproj -o MyApp
……ここでConsoleApp1はソリューションの名前、MyAppはアプリケーションが公開される出力ディレクトリの名前です。必要に応じてDEBUGモードで公開することもできます。
12. 出力ディレクトリとそのすべての内容をPLCにコピーします(例:scpまたはWinSCPを使用)。
scp -r MyApp admin@192.168.1.10:~
13. PLCでシェルセッションを開きます(例:sshまたはPuTTYを使用)。
14. 実行ファイルに実行権限があることを確認します:
$ chmod a+x /opt/plcnext/MyApp/ConsoleApp1
15. アプリケーションを実行します:
$ /opt/plcnext/MyApp/ConsoleApp1
出力は以下のようになります:
Board Temperature = 50°C MainInstance1.AI1 = 0 Board Temperature = 50°C MainInstance1.AI1 = 0 Board Temperature = 50°C MainInstance1.AI1 = 0 Board Temperature = 50°C MainInstance1.AI1 = 0
16. PLCnext Engineerでオンラインになり、AI1変数の値を変更します。アプリケーションが報告する値が変わるはずです。
参考資料とその他のリソース
1. .NET Core ❤ gRPC
2. .NETクライアントでgRPCサービスを呼び出す
3. gRPCに関する有用なリソースのキュレートされたリスト
産業技術
- 電気自動車の急増:高まる需要がグローバルサプライチェーンをどう変えるか
- COVID-19ワクチン配送に向けたコールドチェーン物流の最適化
- ファインアートロジスティクス:グローバルアート市場を革新する
- 迫り来るサプライチェーン混乱を乗り切るプロアクティブ戦略
- コンデンサバンク容量(µF・kVAR)の正確な計算法:力率改善のための3つの手法
- 理想的な生産管理ツールの定義:主要機能とベストプラクティス
- Intel Edison IoT:次世代IoTプロトタイプに最適なミニコンピューター選び
- C#でPLCnextコンソールアプリケーションを開発:初心者ガイド
- 航空機製造におけるレーザー計測:精密品質管理の革新
- 正確な油圧フィッティング測定ガイド:ステップバイステップで漏れゼロを実現
- 油圧モータ速度制御:PWM・リモート制御・最新デジタル技術の実践ガイド