Skip to Content
IoT 앱 개발다른 앱의 데이터 사용

다른 앱의 데이터 사용

모든 IronFlock 앱은 프라이빗하고 격리된 데이터 백엔드를 갖습니다: 자체 테이블, 자체 라이브 스트림, 자체 렐름. 이 격리가 앱을 안전하게 설치할 수 있게 하는 핵심입니다 — 하지만 격리만으로는 모든 앱이 사일로가 되어 버립니다. 수집기 앱이 기계에서 모은 데이터의 가치는 그 앱 하나를 훨씬 넘어섭니다: 대시보드, 분석, 머신러닝 모델, 리포트의 원재료이기 때문입니다.

크로스 앱 데이터 액세스는 설치된 앱을 빌딩 블록으로 바꿉니다. 앱은 같은 프로젝트에 있는 다른 앱의 데이터 — 라이브 이벤트 스트림과 기록된 이력 — 를 읽고 싶다고 선언할 수 있습니다. 프로젝트를 소유한 사용자가 앱별로, 언제든 전환할 수 있는 스위치로 허용 여부를 결정합니다. 나머지는 플랫폼이 강제합니다: 액세스는 엄격히 읽기 전용이며, 제공 앱이 실제로 공유하는 테이블로 범위가 제한되고, 프로젝트 경계를 절대 넘지 않습니다.

무엇이 가능해지는가

  • 수집기 위의 기성 분석. 기계에 데이터 수집기를 설치한 다음, 수집기의 측정값을 사용하는 OEE 대시보드 앱을 설치하세요 — 통합 프로젝트도, 데이터 내보내기도, 글루 코드도 필요 없습니다.
  • 배관 작업 없는 머신러닝. 예지보전 앱은 다른 앱이 이미 수집한 수개월치 진동·온도 이력으로 학습하고, 스트리밍되어 들어오는 라이브 측정값을 실시간으로 스코어링할 수 있습니다.
  • 모놀리스 대신 전문화된 앱. 수집, 변환, 시각화, 리포팅을 각각 한 가지 일을 잘하는 별도의 앱으로 나누고, 레고 블록처럼 프로젝트별로 조합하세요.
  • 사일로가 아닌 에코시스템. 다른 앱의 데이터로 무엇을 하는지가 곧 가치인 앱을 게시하세요. App Store 목록 페이지는 앱이 어떤 데이터를 공유하고 어떤 데이터를 요청하는지 사용자에게 보여줍니다.

작동 방식

세 당사자가 관여하며, 각자 자신의 것을 계속 통제합니다:

  1. 제공 앱(“앱 B”)은 모든 앱과 마찬가지로 자신의 data-template.yml에 테이블과 변환을 정의합니다. 기본적으로 모든 것이 공유 가능하며, 개별 테이블은 private로 표시할 수 있습니다.
  2. 소비 앱(“앱 A”)은 자신의 data-template.yml에 어떤 앱에서 읽고 싶은지, 그리고 그 이유를 선언합니다.
  3. 사용자는 두 앱을 프로젝트에 설치하고 액세스를 승인합니다 — 설치 시점에, 또는 나중에 프로젝트 앱 설정의 앱별 스위치로. 승인이 없으면 액세스도 없습니다: 선언만으로는 아무것도 부여되지 않습니다.

데이터는 프로젝트를 절대 벗어나지 않습니다. 제공 앱의 개발자는 여전히 사용자의 데이터에 접근할 수 없습니다 — 이 권한 부여는 프로젝트 소유자의 통제 아래 한 프로젝트 안에 설치된 앱들 사이에서 이루어집니다.

하나의 표준화된 프로젝트 데이터베이스, 여러 개의 격리된 백엔드

내부적으로 모든 IronFlock 프로젝트는 동일한 표준화된 시계열 데이터베이스를 프로비저닝합니다. 그 안에서 설치된 각 앱은 프라이빗하고 분리된 백엔드 공간을 소유합니다: 앱의 테이블은 자체 데이터베이스 스키마에 존재하며, 사용자가 읽기 액세스를 부여하지 않는 한 다른 어떤 앱에서도 보이지 않습니다. 프로젝트당 하나의 데이터베이스라는 이 설계가 전체 모델을 작동하게 만듭니다:

  • 프로젝트 간 재현 가능. 앱의 데이터 백엔드는 설치되는 모든 프로젝트에서 동일하게 프로비저닝됩니다 — 같은 테이블, 같은 타입, 같은 쿼리 동작. 프로젝트가 관리형 클라우드에서 실행되든 온프레미스 어플라이언스에서 실행되든 마찬가지입니다. 한 번 만들어 두면 어디서나 동일하게 동작합니다.
  • 중앙 수집·점검 지점. 프로젝트 소유자는 모든 앱의 데이터를 한 곳에서 봅니다 — 앱별로 흩어진 저장소가 아니라, 점검하고 쿼리하고 소유할 수 있는 하나의 데이터베이스입니다.
  • 기본은 격리, 공유는 권한 부여로. 스키마 격리가 각 앱의 공간을 프라이빗하게 유지합니다. 크로스 앱 권한 부여는 다른 앱의 스키마로 향하는 읽기 전용 창을 엽니다 — 같은 데이터베이스 안에서 이루어지므로 아무것도 복사되거나 내보내지거나 동기화되지 않습니다. 데이터의 집은 하나이며, 바뀌는 것은 액세스뿐입니다.

의존성 선언

소비 앱은 읽으려는 앱을 자신의 .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: "이 프로젝트에 있는 모든 앱의 라이브 및 이력 데이터 위에 플로우를 구축할 수 있습니다"

"*" 와일드카드는 프로젝트의 모든 앱에 대한 읽기 액세스를 부여합니다 — 사용자가 나중에 설치하는 앱까지 포함하며, 재동의가 필요 없습니다. 모델의 나머지는 모두 그대로입니다: 여전히 읽기 전용이고, 프라이빗 테이블과 변환은 여전히 절대 공유되지 않으며, 플랫폼 앱은 범위 밖입니다. 사용자는 (앱별 목록 대신) 하나의 전부-아니면-전무 스위치로 와일드카드를 승인하며, 언제든 철회할 수 있습니다.

와일드카드 소비 앱은 제공 앱의 이름을 미리 알지 못하므로, 런타임에 이를 검색합니다:

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 대시보드, 예지보전 모델, 에너지 분석이 이를 소비하며, 각각 독립적으로 설치되고 독립적으로 권한이 부여됩니다.

Last updated on