消费其他应用的数据
每个 IronFlock 应用都拥有一个私有、隔离的数据后端:自己的表、自己的实时数据流、自己的独立领域。正是这种隔离让应用可以被放心安装——但如果仅止于此,每个应用也会因此变成一座孤岛。采集应用从一台机器上收集的数据,其价值远远超出这一个应用本身:它是仪表板、分析、机器学习模型和报表的原材料。
**跨应用数据访问把已安装的应用变成可组合的构建模块。**一个应用可以声明它想要读取同一项目中另一个应用的数据——包括其实时事件流和已记录的历史数据。拥有该项目的用户决定是否允许这一访问,按应用逐个授权,并且随时可以通过一个开关改变决定。其余的一切由平台强制执行:访问严格只读,范围仅限于提供方应用实际共享的表,并且绝不跨越项目边界。
这让哪些事情成为可能
- 在采集器之上直接运行现成的分析。 在您的机器上安装数据采集器,再安装一个消费采集器测量值的 OEE 仪表板应用——无需集成项目、无需数据导出、无需胶水代码。
- 没有数据管道负担的机器学习。 预测性维护应用可以基于另一个应用已经采集的数月振动和温度历史进行训练,并在实时读数流入时进行评分。
- 专精的应用,而非庞然大物。 将采集、转换、可视化和报表拆分为各司其职的独立应用——并像乐高积木一样按项目自由组合。
- 一个生态系统,而非一座座孤岛。 发布一个其全部价值就在于处理其他应用数据的应用。App Store 的应用页面会向用户展示一个应用共享哪些数据、请求哪些数据。
工作原理
整个机制涉及三方,每一方都掌控属于自己的部分:
- 提供方应用(“应用 B”)像所有应用一样,在其
data-template.yml中定义表和转换。默认情况下一切都可共享;单个表可以标记为private。 - 消费方应用(“应用 A”)在它自己的
data-template.yml中声明它想读取哪些应用的数据,以及原因。 - 用户在一个项目中安装这两个应用并批准该访问——可以在安装时批准,也可以之后在项目的应用设置中通过按应用设置的开关批准。没有批准就没有访问:仅有声明不会授予任何权限。
数据永远不会离开项目。提供方应用的开发者依然无法访问用户的数据——授权发生在同一项目内已安装的应用之间,由项目所有者掌控。
一个标准化的项目数据库,多个相互隔离的后端
在底层,每个 IronFlock 项目配置的都是同一个标准化的时序数据库。在这个数据库内部,每个已安装的应用都拥有一个私有、彼此分离的后端空间:它的表位于自己专属的数据库 schema 中,除非用户授予读取权限,否则对其他任何应用都不可见。这种“每个项目一个数据库”的设计正是整个模型得以成立的基础:
- 跨项目可复现。 应用的数据后端在其安装到的每个项目中都以完全相同的方式配置——相同的表、相同的类型、相同的查询行为,无论项目运行在托管云中还是本地一体机上。只需针对它构建一次,它在任何地方的行为都一样。
- 一个集中的采集与检查点。 项目所有者可以在一处看到其所有应用的数据——只需检查、查询和拥有一个数据库,而不是一堆分散在各个应用中的存储。
- 默认隔离,按授权共享。 Schema 隔离让每个应用的空间保持私有。一次跨应用授权会向另一个应用的 schema 打开一扇只读窗口——就在同一个数据库内部,因此没有任何数据被复制、导出或同步。数据只有一个家;变化的只是访问权限。
声明依赖
消费方应用在其 .ironflock/data-template.yml 中声明它要读取的应用:
consumes:
- app: machine-monitor
reason: "根据监控应用的机器状态和计数器数据流计算 OEE"
data:
tables:
- tablename: oee_results
columns:
# ... your app's own tables, as usualapp 字段是提供方应用的技术名称(显示在其 App Store 页面上)。reason 会在授权对话框中展示给用户——请把它写给一个正在决定是否信任您应用的人看。
读取数据
在运行时,SDK 会连接到提供方应用的数据后端,并提供与您操作自己的表时完全相同的读取 API:
Python
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 运行时、一个 notebook、一个报表工具——它们的全部价值就在于让用户能够处理项目中恰好存在的任意数据。这类应用无法预先指名提供方;它并不知道用户将会安装哪些采集器或分析应用。对于这类应用,请声明一个通配符:对项目中每个应用数据的读取权限。
consumes:
- app: "*" # the quotes are REQUIRED — a bare * is a YAML alias
reason: "让您能够基于本项目中每个应用的实时数据和历史数据构建流程""*" 通配符会授予对项目中所有应用的读取权限——包括用户之后才安装的应用,且无需再次授权。该模型的其余一切都保持不变:它依然严格只读,私有表和转换依然永远不会被共享,平台应用则不在范围内。用户通过单个“全有或全无”的开关(而非逐个应用的列表)来批准该通配符,并且随时可以撤销。
由于使用通配符的消费方应用无法预先知道提供方的名称,它会在运行时发现它们:
Python
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() 是基础原语——一次调用,不打开任何连接,返回每个提供方的非私有目录,以便您渲染一个选择器。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 ..."用户始终掌控一切
- 在安装时,用户可以确切地看到新应用想要读取哪些已安装应用的数据以及原因——并且可以拒绝其中任何一项。拒绝绝不会阻止安装;应用只是拿不到那些数据而已。
- 每一项已授予的访问都会以项目应用设置中的一个开关的形式出现,可以随时撤销(或之后再授予,例如在提供方应用安装之后)。
- 授权按项目生效。在另一个项目中安装同一对应用时,一切从零开始。
一种典型的组合方式
让这一切变得具体的模式——把采集、分析和可视化拆分为独立、可组合的应用——在工厂数据提取中有端到端的描述:协议采集器提取机器数据,OEE 仪表板、预测性维护模型或能源分析应用消费这些数据,每个应用都独立安装、独立授权。