C# で PLCnext Control gRPC サーバーのクライアントを作成する方法
ファームウェア バージョン 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 で入手できます。
この記事では、C# で単純な gRPC クライアント アプリケーションを作成し、PLCnext Control デバイスで実行する方法について説明します。
前提条件
以下の手順では以下を使用します:
- ファームウェア バージョン 2022.0.3 LTS 以降を実行する AXC F 2152。
- PLCnext Engineer バージョン 2022.0.1 LTS 以降
- Visual Studio 2019 (任意のエディション)
- この Makers ブログの投稿で紹介されている概念:C# で簡単な PLCnext コンソール アプリケーションを作成する方法
- PLCnext/gRPC Github リポジトリの protobuf ディレクトリにある、gRPC サーバーの protobuf 定義ファイル。
- デバイス ステータス RSC サービス。
- データ アクセス RSC サービス。
手順
1. Web ベースの管理ページを使用して、GRPC LOCAL SERVER という名前のサービスが有効になっていることを確認します。
2. ターゲット デバイス用の新しい PLCnext Engineer プロジェクトを作成します。このプロジェクトには以下が必要です:
- INT 型の AI1 という OUT ポート変数を持つプログラム
- MainInstance1 というプログラムのインスタンス
3. PLCnext Engineer プロジェクトをターゲット デバイスに送信します。
4. Visual Studio で、以前の Makers ブログ投稿で説明されている手順のステップ 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()
{
// The code to connect to a Unix Domain Socket is from:
// 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
};
// Create a gRPC channel to the PLCnext unix socket
using var channel = GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions
{
HttpHandler = socketsHttpHandler
});
// Create a gRPC client for the Device Status Service on that channel
var grpc_status_client = new IDeviceStatusService.IDeviceStatusServiceClient(channel);
// Create a gRPC client for the Data Access Service on that channel
var grpc_data_client = new IDataAccessService.IDataAccessServiceClient(channel);
// Create an item to get from the Device Status Service
// Item identifiers are listed in the 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";
// Create a variable to get from the Data Access Service
var data = new IDataAccessServiceReadSingleRequest();
data.PortName = "Arp.Plc.Eclr/MainInstance1.AI1";
// Response variables
IDeviceStatusServiceGetItemResponse grpc_status_response;
IDataAccessServiceReadSingleResponse grpc_data_response;
// Endless loop
while (true)
{
// Request the item from the Device Status Service
grpc_status_response = grpc_status_client.GetItem(item);
// Request data from the Data Access Service
grpc_data_response = grpc_data_client.ReadSingle(data);
// Report the results
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);
// Wait for 1 second
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. (たとえば) scp または WinSCP を使用して、出力ディレクトリとそのすべての内容を PLC にコピーします。
scp -r MyApp admin@192.168.1.10:~
13. (たとえば) ssh または PuTTY を使用して、PLC でシェル セッションを開きます。
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ワクチン需要に対応するコールドチェーンを準備する方法
- ファインアートロジスティクスがアートマーケットをどのように変えているか
- 次のサプライチェーンの混乱に備える方法
- P.F改善のためのμファラッドとkVARでの適切なコンデンササイズの計算方法
- 生産管理のための理想的なツールはどのようなものでしょうか?
- Intel Edison IoT:IoTプロトタイプにIntelEdisonを選択する方法
- C# で簡単な PLCnext コンソール アプリケーションを作成する方法
- 必要な油圧フィッティングの測定方法は?
- 油圧モーターの速度はどのように制御しますか?