Skip to Content
IoT アプリ開発他アプリのデータを利用

他のアプリのデータの利用

すべてのIronFlockアプリは、プライベートで分離されたデータバックエンドを持ちます:独自のテーブル、独自のライブストリーム、独自のレルム。この分離こそが、アプリを安全にインストールできる理由です — しかし分離だけでは、すべてのアプリがサイロになってしまいます。コレクターアプリが機械から収集するデータの価値は、その1つのアプリをはるかに超えます:ダッシュボード、分析、機械学習モデル、レポートの原材料なのです。

クロスアプリデータアクセスは、インストール済みのアプリをビルディングブロックに変えます。 アプリは、同じプロジェクト内の別のアプリのデータ — そのライブイベントストリームと記録された履歴 — を読み取りたいと宣言できます。プロジェクトを所有するユーザーが、アプリごとに、いつでも切り替えられるスイッチで許可するかどうかを決定します。残りはプラットフォームが強制します:アクセスは厳密に読み取り専用で、提供側アプリが実際に共有しているテーブルに限定され、プロジェクトの境界を越えることは決してありません。

これで可能になること

  • コレクターの上に既製の分析を。 機械にデータコレクターをインストールし、次にそのコレクターの測定値を利用するOEEダッシュボードアプリをインストールします — 統合プロジェクトも、データエクスポートも、グルーコードも不要です。
  • 配管工事なしの機械学習。 予知保全アプリは、別のアプリがすでに収集した数か月分の振動・温度履歴で学習し、ストリーミングされてくるライブの読み取り値をリアルタイムでスコアリングできます。
  • モノリスではなく専門特化したアプリ。 収集、変換、可視化、レポートを、それぞれが1つのことをうまくこなす個別のアプリに分割し、レゴブロックのようにプロジェクトごとに組み合わせられます。
  • サイロではなくエコシステム。 他のアプリのデータをどう活用するかにこそ価値があるアプリを公開できます。App Storeの掲載ページには、アプリがどのデータを共有し、どのデータをリクエストするかがユーザーに表示されます。

仕組み

3つの当事者が関わり、それぞれが自分のものを管理し続けます:

  1. 提供側アプリ(「アプリB」)は、すべてのアプリと同様に、自身のdata-template.ymlでテーブルと変換を定義します。デフォルトではすべてが共有可能で、個々のテーブルをprivateとしてマークできます。
  2. 利用側アプリ(「アプリA」)は、自身のdata-template.ymlで、どのアプリから読み取りたいのか、そしてその理由を宣言します。
  3. ユーザーは両方のアプリをプロジェクトにインストールし、アクセスを承認します — インストール時に、または後からプロジェクトのアプリ設定にあるアプリごとのスイッチで。承認がなければアクセスもありません:宣言だけでは何も付与されません。

データがプロジェクトの外に出ることはありません。提供側アプリの開発者は依然としてユーザーのデータにアクセスできません — 付与されるのは、プロジェクト所有者の管理下にある1つのプロジェクト内のインストール済みアプリ間のアクセスです。

1つの標準化されたプロジェクトデータベース、多数の分離されたバックエンド

内部的には、すべてのIronFlockプロジェクトは同じ標準化された時系列データベースをプロビジョニングします。その中で、インストールされた各アプリはプライベートで分離されたバックエンド空間を所有します:そのテーブルは独自のデータベーススキーマ内にあり、ユーザーが読み取りアクセスを付与しない限り、他のどのアプリからも見えません。このプロジェクトごとに1つのデータベースという設計こそが、モデル全体を機能させています:

  • プロジェクト間で再現可能。 アプリのデータバックエンドは、インストールされるすべてのプロジェクトで同一にプロビジョニングされます — 同じテーブル、同じ型、同じクエリ動作。プロジェクトがマネージドクラウドで動いていても、オンプレミスのアプライアンスで動いていても変わりません。一度そこに向けて構築すれば、どこでも同じように動作します。
  • 中央の収集・検査ポイント。 プロジェクト所有者は、すべてのアプリのデータを1か所で確認できます — アプリごとに散在するストアではなく、検査し、クエリし、所有できる1つのデータベースです。
  • デフォルトで分離、付与によって共有。 スキーマ分離により、各アプリの空間はプライベートに保たれます。クロスアプリの付与は、別のアプリのスキーマへの読み取り専用の窓を開きます — 同じデータベースの内側なので、何もコピーされず、エクスポートされず、同期もされません。データの置き場所は1つのまま、変わるのはアクセスだけです。

依存関係の宣言

利用側アプリは、読み取り対象のアプリを自身の.ironflock/data-template.ymlで表明します:

consumes: - app: machine-monitor reason: "モニターの機械状態ストリームとカウンターストリームからOEEを計算します" data: tables: - tablename: oee_results columns: # ... your app's own tables, as usual

appフィールドは、提供側アプリの技術的なアプリ名です(そのアプリのApp Storeページに表示されます)。reasonは同意ダイアログでユーザーに表示されます — あなたのアプリを信頼するかどうかを判断する人間に向けて書いてください。

データの読み取り

実行時には、SDKが提供側アプリのデータバックエンドに接続し、自分のテーブルにすでに使っているのと同じ読み取りAPIを提供します:

from ironflock import IronFlock flock = IronFlock() # Connect to the providing app's data backend (requires the user's grant) monitor = await flock.connect_to_app("machine-monitor") # Discover what it shares print(monitor.tables) # shared tables with their columns print(monitor.transforms) # shared transforms (views) # Query history rows = await monitor.get_history("machinestate", {"limit": 1000}) # Down-sampled series for charts and models series = await monitor.get_series_history("measurements", { "metrics": ["temperature"], "method": "AVG", "timeRange": ["2026-07-01T00:00:00Z", "2026-07-04T00:00:00Z"], }) # Subscribe to live rows as they are collected async def on_row(row): print("live reading:", row) await monitor.subscribe_to_table("measurements", on_row)

ユーザーがアクセスを付与していない場合(または後で取り消した場合)、connectToAppは明確な型付きエラーで失敗します — アプリはこのデータソースをオプションとして扱い、グレースフルにデグレードするように作るべきです。

プロジェクトの全データを利用する(ワイルドカード)

アプリの中には、汎用的なデータワークベンチ — Node-REDランタイム、ノートブック、レポートツール — もあり、その全価値は、プロジェクトに存在するあらゆるデータをユーザーが扱えるようにすることにあります。こうしたアプリは、提供側アプリを事前に名指しできません。ユーザーがどのコレクターや分析アプリをインストールするか分からないからです。こうしたアプリ向けには、ワイルドカードを宣言します:プロジェクト内のすべてのアプリのデータへの読み取りアクセスです。

consumes: - app: "*" # the quotes are REQUIRED — a bare * is a YAML alias reason: "このプロジェクト内のすべてのアプリのライブデータと履歴データの上にフローを構築できます"

"*"ワイルドカードは、プロジェクト内のすべてのアプリへの読み取りアクセスを付与します — ユーザーが後からインストールするアプリも含め、再同意は不要です。モデルのそれ以外の点はすべて変わりません:依然として読み取り専用であり、プライベートなテーブルや変換は依然として一切共有されず、プラットフォームアプリは対象外です。ユーザーは、(アプリごとのリストではなく)1つのオール・オア・ナッシングのスイッチでワイルドカードを承認し、いつでも取り消せます。

ワイルドカードを使う利用側アプリは、提供側アプリの名前を事前に知らないため、実行時にそれらを検出します:

from ironflock import IronFlock flock = IronFlock() # Discover every app whose data you may read (name + shared-table catalog) providers = await flock.list_consumable_apps() for p in providers: print(p["app"], p["stages"]) # e.g. "energy-monitor", {"prod": {"tables": [...]}} # Open one by name (works because you hold the wildcard grant) energy = await flock.connect_to_app("energy-monitor") rows = await energy.get_history("meterdata", {"limit": 1000}) # ...or open them all at once all_apps = await flock.connect_to_all_apps() for app in all_apps: await app.subscribe_to_table(app.tables[0]["tablename"], on_row)

listConsumableApps()はプリミティブです — 1回の呼び出しで、接続は一切開かず、各提供側アプリの非プライベートなカタログを返すので、ピッカーを描画できます。connectToAllApps()は、それらをすべて開く便利な一括版です。新しくインストールされたアプリは、次回のlistConsumableApps()呼び出しで自動的に現れます。ユーザーがワイルドカードを付与していない場合、どちらも型付きのNO_GRANTエラーで失敗します。

構造として読み取り専用

この付与は、慣習によってではなく、プラットフォームのメッセージング層によって強制されます。利用側アプリにできること・できないこと:

可能不可能
提供側のライブデータストリームへのサブスクライブ提供側のデータの書き込み、変更、削除
提供側の記録された履歴のクエリ提供側のカスタムプロシージャやコマンドの呼び出し
共有された変換(ビュー)の読み取りprivateとマークされたテーブルや変換の閲覧
共有テーブルカタログの検出他のプロジェクトのアプリのデータへの到達

アプリのデータを共有する — 一部は手元に残しながら

価値あるデータを収集するアプリを作るなら、そのデータを共有することで、あなたのアプリは他者がその上に構築する基盤になります。すべてを共有する必要はありません:内部用のテーブルや変換をprivateとマークすれば、共有カタログから完全に姿を消します — リストされず、クエリできず、ストリーミングもされません。

data: tables: - tablename: measurements # shared (default) columns: [ ... ] - tablename: calibration_state # internal — never visible to other apps private: true columns: [ ... ] transforms: - tablename: hourly_aggregates # shared views work like shared tables sql: "SELECT ..."

ユーザーが主導権を持ち続ける

  • インストール時に、ユーザーは新しいアプリがどのインストール済みアプリから読み取りたいのか、そしてその理由を正確に確認でき、そのいずれも拒否できます。拒否してもインストールがブロックされることはありません。アプリが単にそのデータを取得できないだけです。
  • 付与されたすべてのアクセスは、プロジェクトのアプリ設定内のスイッチとして表示され、いつでも取り消せます(あるいは、提供側アプリのインストール後など、後から付与することもできます)。
  • 付与はプロジェクト単位です。同じ2つのアプリの組み合わせを別のプロジェクトにインストールすると、ゼロからのスタートになります。

典型的な構成

このモデルを具体化するパターン — 収集、分析、可視化を個別の組み合わせ可能なアプリとして扱う — は、工場データ抽出でエンドツーエンドに説明されています:プロトコルコレクターが機械データを抽出し、OEEダッシュボード、予知保全モデル、エネルギー分析がそれを利用します — それぞれが独立してインストールされ、独立して権限を付与されます。

Last updated on