0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ORiN3を使ってデバイスにアクセスしてみる - C#編

Last updated at Posted at 2025-05-13

ORiN3を使ってデバイスにアクセスしてみる

はじめに

前回の記事でORiN3のセットアップを行い、GUIベースで簡単な動作確認を行いました。
今回は、C#でORiN3にアクセスしてみようと思います。

この記事では以下の流れで説明していきます:

  1. C#のプロジェクトの作成
  2. nupkgの設定
  3. サンプルプログラムを使ったデータアクセス

1. C#のプロジェクト作成

まずは、ORiN3を扱うためのC#プロジェクトを作成します。
Visual Studio 2022を使いますがVisual Studio Codeなど別のIDEでも構いません。

プロジェクトを新規作成

コンソールアプリのプロジェクトを新規作成します。

image.png

プロジェクト名はなんでも良いですが『ORiN3Sample』としました。

image.png

ORiN3のアクセスに必要なnupkgは.NET Standard2.1がターゲットになっています。
対応可能なフレームワークであればどれを選択しても良いですが今回は.NET8.0を選択しました。
作成ボタンをクリックしてください。

image.png

2. nupkgの設定

次は必要なnupkgを設定していきます。

NuGetパッケージマネージャーを開く

プロジェクトの依存関係をクリックしてNuGetパッケージマネージャーを起動します。

image.png

nupkeのインストール

参照タブで Message.Client.ORiN3 を検索して以下のnupkgをインストールします。

  • Message.Client.ORiN3.Provider
  • Message.Client.ORiN3.RemoteEngine

image.png

3. サンプルプログラムを使ったデータアクセス

次にサンプルプログラムを作っていこうと思います。

コードの自動生成

ORiN3の設定は ORiN3入門:環境構築ガイド+GUIツールで動かしてみる② で作成したプロジェクトを使います。

このような設定になっているはずです。

image.png

ORiN3 Configurator のオブジェクトエクスプローラー上でMockプロバイダを右クリックしてソースコード生成を選択します。

image.png

そうするとプロバイダ生成のコードがクリップボードにコピーされますのでそれをIDEに貼り付けてみてください。

自動生成されたMainメソッドの中に貼り付けましたがいくつか調整が必要です。
usingの部分をコードの上部に移動させたのと、Mainメソッドをasyncに変更しました。

image.png

この状態でORiN3プロバイダーの起動・終了ができるはずです。

トラブルシューティング

もしもうまくいかない場合は以下を確認ください。

プロキシの設定

Message.Client.ORiN3 はgRPCで ORiN3 Remote EngineORiN3 Provider と通信を行います。
これはHTTPの通信になりますのでプロキシが設定されていると意図した接続先につなげられないことがあります。

ORiN3 Remote Engineを別PCで起動している場合

ORiN3はセキュリティの都合上、デフォルト状態ではローカルホスト以外からの接続ができないようになっています。
別PCで起動している ORiN3 Remote Engine に接続する場合は適切な権限設定が必要です。

ControllerとVariableの起動

上記と同様にオブジェクトエクスプローラー上で右クリックしてコードを生成してください。
以下に生成した全コードを貼っておきます。
PulseWaveVariableにアクセスして500msごと取得した値をしコンソールに表示しています。

using Design.ORiN3.Provider.Core.V1.Telemetry;
using Message.Client.ORiN3.Provider.V1;
using Message.Client.ORiN3.RemoteEngine.V1;

namespace ORiN3Sample
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            using var cts = new CancellationTokenSource();

            // Connect to Remote Engine
            using var remoteEngineChannel = Grpc.Net.Client.GrpcChannel.ForAddress("http://127.0.0.1:7103/");
            using var remoteEngine = await RemoteEngine.AttachAsync(remoteEngineChannel, uint.MaxValue, cts.Token).ConfigureAwait(false);

            // Launching Provider
            var providerEndpoints = new ProviderEndpoint[] { new ProviderEndpoint(0, "127.0.0.1", 0, Array.Empty<byte>()) };
            var telemetryEndpoints = new TelemetryEndpoint[] { };
            var telemetryAttributes = new Dictionary<string, string> { };
            var telemetryOption = new TelemetryOption(true, telemetryEndpoints, telemetryAttributes);
            var extensions = new Dictionary<string, string> { };
            var wakeupProviderResult = await remoteEngine.WakeupProviderAsync(
                id: "643D12C8-DCFC-476C-AA15-E8CA004F48E8",
                version: "1.1.0",
                threadSafeMode: true,
                endpoints: providerEndpoints,
                logLevel: ORiN3LogLevel.Information,
                telemetryOption: telemetryOption,
                extension: extensions,
                token: cts.Token).ConfigureAwait(false);

            var providerPort = wakeupProviderResult.ProviderInformation.EndPoints
                .Where(x => Uri.TryCreate(x.Uri, UriKind.Absolute, out _))
                .Select(x => new Uri(x.Uri))
                .First(x => x.Host == "127.0.0.1")
                .Port;

            // Attach RootObject
            using var providerChannel = Grpc.Net.Client.GrpcChannel.ForAddress($"http://127.0.0.1:{providerPort}");
            using var rootObject = await ORiN3RootObject.AttachAsync(providerChannel, uint.MaxValue, cts.Token).ConfigureAwait(false);

            // Create object
            var controllerObject = await rootObject.CreateControllerAsync(
                name: "GeneralPurposeController",
                typeName: "ORiN3.Provider.ORiNConsortium.Mock.O3Object.Controller.GeneralPurposeController, ORiN3.Provider.ORiNConsortium.Mock",
                option: "{\"@Version\":\"1.1.0\"}",
                token: cts.Token).ConfigureAwait(false);

            // Connect
            await controllerObject.ConnectAsync(cts.Token).ConfigureAwait(false);

            // Create object
            var variableObject = await controllerObject.CreateVariableAsync<bool>(
                name: "PulseWaveBoolVariable",
                typeName: "ORiN3.Provider.ORiNConsortium.Mock.O3Object.Variable.PulseWaveBoolVariable, ORiN3.Provider.ORiNConsortium.Mock",
                option: "{\"@Version\":\"1.1.0\"}",
                token: cts.Token).ConfigureAwait(false);

            // Get value
            for (int i = 0; i < 10; i++)
            {
                var value = await variableObject.GetValueAsync(cts.Token).ConfigureAwait(false);
                Console.WriteLine(value);
                await Task.Delay(500).ConfigureAwait(false);
            }

            // Delete object
            await variableObject.DeleteAsync(cts.Token).ConfigureAwait(false);

            // Disconnect
            await controllerObject.DisconnectAsync(cts.Token).ConfigureAwait(false);

            // Delete object
            await controllerObject.DeleteAsync(cts.Token).ConfigureAwait(false);

            // Shutdown Provider
            await rootObject.ShutdownAsync(cts.Token).ConfigureAwait(false);
        }
    }
}

実行結果はこんな感じです。

image.png


関連情報(公式)


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?