Skip to Content

IronFlock SDK

IronFlock SDK, edge uygulamalarınızın IronFlock platformuyla etkileşim kurmasını sağlar. Kayıtlı bir cihazda çalışırken kimlik doğrulamayı otomatik olarak yönetir; veri yayımlama, geçmiş sorgulama, cihazlar arası uzak prosedür çağırma ve cihaz meta verisini güncelleme işlevleri sunar.

SDKPaketGereklilik
Pythonironflock on PyPIPython 3.8+
JavaScriptironflock on npmNode.js 18+ veya modern tarayıcı

Kurulum

pip install ironflock

Ya da uygulamanızın requirements.txt dosyasına ironflock ekleyin.

Hızlı Başlangıç

import asyncio from ironflock import IronFlock async def main(): while True: await ironflock.publish_to_table("sensordata", { "temperature": 22.5, "humidity": 60 }) await asyncio.sleep(5) ironflock = IronFlock(mainFunc=main) ironflock.run()

Bir IronFlock uygulama container’ı içinde kullanıldığında SDK, bağlantı kimlik bilgilerini ortamdan otomatik olarak okur — manuel yapılandırma gerekmez.

Yapıcı Seçenekleri

ironflock = IronFlock( mainFunc=main, # async function to run after connecting serial_number="abc123" # override device serial (optional) )
ParametreAçıklama
mainFuncBağlantı kurulduktan sonra çalışan bir async fonksiyon
serial_numberCihaz seri numarasını geçersiz kılar. Varsayılan: DEVICE_SERIAL_NUMBER ortam değişkeni

Veri Yayımlama

publishToTable / publish_to_table

Bir filo tablosuna veri kaydı yayımlar. Tablo adı, uygulamanızın data-template.yml dosyasında tanımlanan bir tabloyla eşleşmelidir. SDK, veriyi doğru proje veritabanına otomatik olarak yönlendirir.

await ironflock.publish_to_table("sensordata", { "temperature": 22.5, "humidity": 60, "device_id": "sensor-001" })

appendToTable / append_to_table

Yayımla/abone ol yerine uzak prosedür çağrısı kullanarak filo tablosuna veri ekler. Verinin kalıcı hale getirildiğine dair onay gerektiğinde bunu kullanın.

result = await ironflock.append_to_table("sensordata", { "temperature": 22.5, "humidity": 60 })

publishRowsToTable / publish_rows_to_table

Bir filo tablosuna tek bir mesajda birden çok satır (toplu ekleme) yayımlar. Platform, tüm yığını tek bir işlemde atomik olarak (ya hep ya hiç) ekler. Satır başına bir gidiş-dönüşün çok maliyetli olacağı yüksek frekanslı veriler için bunu kullanın. publishToTable gibi bu da gönder-unut prensibiyle çalışır — onay, veritabanı eklemesini değil, yönlendiriciye teslimi doğrular.

await ironflock.publish_rows_to_table("sensordata", [ {"tsp": "2024-01-15T10:30:00.000Z", "temperature": 22.5}, {"tsp": "2024-01-15T10:30:01.000Z", "temperature": 22.7}, ])

İkinci argüman, eklenecek satır nesnelerinden oluşan boş olmayan bir listedir.

appendRowsToTable / append_rows_to_table

Bir filo tablosuna tek bir uzak prosedür çağrısında birden çok satır (toplu ekleme) ekler. Platform, tüm yığını atomik olarak (ya hep ya hiç) ekler: herhangi bir satır geçersizse tüm yığın reddedilir ve hiçbir şey kalıcı hale getirilmez. Ekleme sonucuna ihtiyacınız olduğunda bunu publishRowsToTable / publish_rows_to_table yerine tercih edin.

result = await ironflock.append_rows_to_table("sensordata", [ {"tsp": "2024-01-15T10:30:00.000Z", "temperature": 22.5}, {"tsp": "2024-01-15T10:30:01.000Z", "temperature": 22.7}, ]) # result -> {"success": True, "count": 2}

reportError / report_error

Bir uygulama hatasını filonuzun error-logs tablosuna raporlar. Bu, publishToTable / appendToTable üzerine kullanışlı bir sarmalayıcıdır: satırı source: "app", bir önem level değeri ve bir zaman damgasıyla işaretler, ardından onu herhangi bir normal tablo satırı gibi yazar. Hata, fleetdb sistem hatalarının kullandığı (source: "system" olarak etiketlenmiş) aynı error-logs tablosuna düşer; bu nedenle getHistory ile sorgulanabilir, subscribeToTable / subscribe_to_table ile akışa alınabilir, board-template’lerde kullanılabilir ve transformed.error-logs üzerinde gerçek zamanlı olarak teslim edilir — platformun sistem hatası bildirimini tetiklemeden.

# Fire-and-forget (default): publishes to the error-logs table await ironflock.report_error("Sensor read timed out", level="warn") # Pass an exception to capture its traceback (falls back to the message) try: risky_operation() except Exception as err: await ironflock.report_error(err) # Use the append RPC when you want to await the insert outcome await ironflock.report_error("Calibration failed", level="error", append=True)

Parametreler:

ParametreTürAçıklama
errorstr / string veya istisna / ErrorHata mesajı veya traceback/stack (ya da mesajı) kaydedilen bir istisna
levelstr / string, isteğe bağlıÖnem düzeyi: "error", "warn", "info" veya "debug". Varsayılan "error"
appendbool / boolean, isteğe bağlıtrue olduğunda append RPC kullanılır (ekleme sonucunu döndürür). Varsayılan false (fire-and-forget yayımlama)
tspstr / string, isteğe bağlıISO-8601 zaman damgası geçersiz kılması. Varsayılan olarak geçerli zaman

Python’da seçenekler anahtar kelime argümanlarıdır (report_error(error, level=..., append=..., tsp=...)); JavaScript’te bir seçenekler nesnesi aracılığıyla geçilir (reportError(error, { level, append, tsp })).

publish

Herhangi bir WAMP konusuna mesaj yayımlar. Veritabanı tablosuna eşlenmeyen özel mesajlaşma veya olaylar için bunu kullanın.

await ironflock.publish("com.myapp.alerts", { "level": "warning", "message": "Temperature threshold exceeded" })

Geçmiş Veri Sorgulama

getHistory

Bir filo tablosundan geçmiş verileri getirir. Filtreleme, zaman aralığı ve sayfalama desteklenir.

# Simple query data = await ironflock.getHistory("sensordata", {"limit": 100}) # Query with time range and filters data = await ironflock.getHistory("sensordata", { "limit": 500, "offset": 0, "timeRange": { "start": "2026-01-01T00:00:00Z", "end": "2026-03-01T00:00:00Z" }, "filterAnd": [ {"column": "temperature", "operator": ">", "value": 20}, {"column": "humidity", "operator": "<=", "value": 80} ] }) # Current value(s) only: the "latest" marker returns the newest row per entity current = await ironflock.getHistory("sensordata", { "limit": 100, "filterAnd": [{"latest": True}] })

Sorgu parametreleri:

AlanTürAçıklama
limitint / numberDöndürülecek maksimum satır sayısı (1–10.000, zorunlu)
offsetint / numberSayfalama için kaydırma
timeRangedict / object{"start": "<ISO datetime>", "end": "<ISO datetime>"}
filterAndlist / arrayAND filtre koşulları ve/veya latest işareti (aşağıya bakın)
columnslist / arrayDöndürülecek sütunlar (isteğe bağlı). tsp, device_key ve authid her zaman dahil edilir; tüm sütunlar için bu alanı atlayın

Filtre operatörleri: =, !=, >, <, >=, <=, LIKE, ILIKE, IN, NOT IN, IS, IS NOT

Her filtre column, operator ve value anahtarlarına sahip bir nesnedir.

Güncel değerleri okuma. filterAnd içindeki bir {"latest": true} girdisi bir filtre koşulu değil, bir mod anahtarıdır: veri arka ucu yalnızca varlık başına en yeni satırı döndürür; bu satır, tablonun maintainLatestFlagFor ile bildirdiği varlık anahtarından SQL’de türetilir. Varlık anahtarı olmayan bir tablo, yalnızca en son tek satırını döndürür.

Diğer koşullar bu işaretle beklediğiniz gibi birleşir: varlık anahtarı sütunları üzerindeki koşullar hangi varlıkların döndürüleceğini daraltır; diğer tüm koşullar ve timeRange ise elde edilen en son satırlara uygulanır. Yani {"latest": true} ile bir deleted filtresini birleştirmek, silinen varlıkların önceki satırını yeniden ortaya çıkarmak yerine bu varlıkları gizler.

IronFlock’un önceki sürümleri fiziksel bir latest_flag sütunu saklıyordu. Bu sütun artık mevcut değil — eski bir latest_flag = true filtresi hâlâ kabul edilir ve bu işaret gibi ele alınır, ancak yeni kodlar {"latest": true} kullanmalıdır. latest işareti getSeriesHistory içinde kullanılamaz.

getSeriesHistory / get_series_history

Bir filo tablosundan alt örneklenmiş zaman serisi verileri alır: zaman kovalarında toplanan sayısal sütunlar (ör. saatlik ortalamalar). Uzun zaman aralıklarını kapsayan grafikler için idealdir. Tablolar için kullanılabilir (transform’lar için değil).

series = await ironflock.get_series_history("sensordata", { "metrics": ["temperature", "humidity"], "method": "AVG", "limit": 500, "timeRange": ["2026-01-01T00:00:00Z", "2026-03-01T00:00:00Z"], "groupBy": ["device_id"] })

Sorgu parametreleri:

AlanTürAçıklama
metricslist / arrayAlt örneklenecek sayısal sütunlar
methodstr / stringKova başına toplama: "AVG", "SUM", "COUNT", "MIN", "MAX", "FIRST" veya "LAST"
limitint / numberMaksimum kova sayısı (1–10.000)
timeRangelist / array[start, end] — ISO datetime dizeleri veya epoch-ms sayıları; null = açık uç (zorunlu)
groupBylist / arraySerinin gruplanacağı sütunlar (isteğe bağlı)
filterAndlist / arrayAND filtre koşulları (isteğe bağlı). Yalnızca filtre koşulları — latest işareti burada desteklenmez; güncel değerleri okumak için getHistory kullanın

Veriye Abone Olma

subscribeToTable / subscribe_to_table

Bir filo tablosundaki gerçek zamanlı güncellemelere abone olur. Tabloya yeni veri yayımlandığında işleyici çağrılır. Toplu ekleme yolu (publishRowsToTable / appendRowsToTable) üzerinden yazılan satırlar işleyicinize birer birer teslim edilir, böylece verinin nasıl yazıldığından bağımsız olarak işleyici kodu aynı kalır.

def on_sensor_data(*args, **kwargs): print("New reading:", args, kwargs) await ironflock.subscribe_to_table("sensordata", on_sensor_data)

subscribe

Özel gerçek zamanlı mesajlaşma için herhangi bir WAMP konusuna abone olur.

def on_alert(*args, **kwargs): print("Alert received:", args, kwargs) await ironflock.subscribe("com.myapp.alerts", on_alert)

Uygulamalar Arası Veri Erişimi

Başka bir uygulamanın filo verilerini, aynı proje içinde kendi uygulamanızın içinden okuyun. Sağlayıcı uygulama, data-template.yml dosyasının consumes: bölümünde sizin uygulamanızı belirtmeli ve proje kullanıcısı erişim izni vermelidir. Erişim salt okunurdur: sağlayıcının paylaştığı tabloların ve transform’ların geçmişini sorgulayabilir ve satırlarına gerçek zamanlı olarak abone olabilirsiniz, ancak bunlara yazamazsınız. Tüketilen uygulamalara yapılan bağlantılar uygulama başına önbelleğe alınır ve örneğiniz durduğunda otomatik olarak kapatılır.

Uygulamanız joker karakter (wildcard) iznine (consumes: [{ app: "*" }]) sahipse, sağlayıcıları listConsumableApps / list_consumable_apps ve connectToAllApps / connect_to_all_apps (aşağıda) ile dinamik olarak keşfedebilir ve açabilirsiniz.

connectToApp / connect_to_app

Başka bir uygulamanın veri arka ucuna salt okunur bir bağlantı açar ve bir tanıtıcı (handle) döndürür. Tanıtıcı getHistory / get_history, subscribeToTable / subscribe_to_table ve getSeriesHistory / get_series_history (yalnızca tablolar) işlevlerini sunar — kendi tablolarınızda kullandığınız sorgulama ve abone olma işlemlerinin aynısı — ayrıca close ile paylaşılan tables / transforms kataloglarını da sağlar.

# Open a read-only handle on another app's data backend weather = await ironflock.connect_to_app("weather-app") # Inspect what the provider shares print([t["tablename"] for t in weather.tables]) # Query history and subscribe, just like your own tables rows = await weather.get_history("forecasts", {"limit": 100}) def on_forecast(*args, **kwargs): print("New forecast:", args) await weather.subscribe_to_table("forecasts", on_forecast)

Parametreler:

ParametreTürAçıklama
app_name / appNamestr / stringconsumes: bölümünüzde belirtildiği gibi sağlayıcı uygulamanın adı
stagestr / string, isteğe bağlıSağlayıcı aşaması (stage): "dev" veya "prod". Varsayılan olarak kendi uygulamanızın aşaması
on_error / onErrorcallable, isteğe bağlıBağlantı kurulduktan sonra erişim reddedilirse (ör. izin daha sonra iptal edilirse) bir CrossAppAccessError ile çağrılır

Erişim reddedilir veya yanlış kullanılırsa, code alanına sahip bir CrossAppAccessError yükseltilir (Python) / fırlatılır (JavaScript): NO_GRANT, PROVIDER_NOT_INSTALLED, UNKNOWN_APP, PRIVATE_TABLE veya NOT_AUTHORIZED.

Python’da stage ve on_error anahtar kelime argümanlarıdır; JavaScript’te bir seçenekler nesnesi aracılığıyla geçilir (connectToApp(appName, { stage, onError })).

listConsumableApps / list_consumable_apps

Projedeki her özel olmayan sağlayıcıyı listeler — bu, joker karakter tüketim iznine (data-template.yml dosyanızdaki consumes: [{ app: "*" }], proje kullanıcısı tarafından verilir) sahip uygulamalar için temel keşif işlevidir. Tek bir çağrı yapar ve hiçbir bağlantı açmaz: döndürülen katalogları bir seçicide gösterin, ardından istediğiniz sağlayıcılar için connectToApp / connect_to_app çağırın — veya hepsini tek seferde açmak için connectToAllApps / connect_to_all_apps çağırın.

Not: İzni uygulamanızın data-template.yml dosyasında belirtin ve * işaretini tırnak içine alın — tırnaksız bir *, bir YAML takma adıdır ve ayrıştırılamaz:

consumes: - app: "*"
providers = await ironflock.list_consumable_apps() for p in providers: print(p["app"], list(p["stages"].keys())) # e.g. "weather-app" ["dev", "prod"]

Her giriş bir sağlayıcıyı tanımlar:

AlanTürAçıklama
appstr / stringSağlayıcı uygulama adı
provider_app_keyint / numberSağlayıcının uygulama anahtarı
stagesdict / objectAşama başına katalog { dev?, prod? }; bir aşama yalnızca sağlayıcının o aşama için bir veri arka ucu varsa mevcuttur. Her katalog, paylaştığı özel olmayan tables ve transforms öğelerini içerir

Uygulamanızın hiçbir joker karakter izni yoksa, code: NO_GRANT içeren bir CrossAppAccessError yükseltilir (Python) / fırlatılır (JavaScript).

connectToAllApps / connect_to_all_apps

Projedeki her özel olmayan sağlayıcıya tek bir çağrıda salt okunur tanıtıcılar (handle) açar (yalnızca joker karakter tüketicileri). Sağlayıcıları listConsumableApps / list_consumable_apps aracılığıyla numaralandırır ve her birini açar; istenen aşama için veri arka ucu bulunmayanları atlar. Her tanıtıcı, connectToApp / connect_to_app ile aynı anahtar altında önbelleğe alınır, böylece daha sonraki bir connectToApp(name) çağrısı zaten hazırlanmış tanıtıcıyı döndürür. Döndürülen tanıtıcılar, örneğiniz durduğunda birlikte kapatılır.

apps = await ironflock.connect_to_all_apps( on_error=lambda err: print("Provider skipped:", err) ) for app in apps: rows = await app.get_history(app.tables[0]["tablename"], {"limit": 10}) print(app.app, rows)

Parametreler:

ParametreTürAçıklama
stagestr / string, isteğe bağlıSağlayıcı aşaması (stage): "dev" veya "prod". Varsayılan olarak kendi uygulamanızın aşaması
continue_on_error / continueOnErrorbool / boolean, isteğe bağlıtrue olduğunda (varsayılan), açılamayan bir sağlayıcı on_error / onError’a bildirilir ve sonuçtan çıkarılır. false olduğunda, ilk hata yükseltilir/fırlatılır
on_error / onErrorcallable, isteğe bağlıAçılamayan her sağlayıcı ile çağrılır (continue_on_error / continueOnError true iken) ve zaten açılmış bir bağlantı daha sonra reddedilirse (ör. izin daha sonra iptal edilirse) bir CrossAppAccessError ile çağrılır

Başarıyla açılan sağlayıcı tanıtıcılarını döndürür (connectToApp / connect_to_app ile aynı tanıtıcı türü). Uygulamanızın hiçbir joker karakter izni yoksa, code: NO_GRANT içeren bir CrossAppAccessError yükseltilir (Python) / fırlatılır (JavaScript).

Python’da stage, on_error ve continue_on_error anahtar kelime argümanlarıdır; JavaScript’te bir seçenekler nesnesi aracılığıyla geçilir (connectToAllApps({ stage, onError, continueOnError })).

Yönetilen Dosya Depolama

Her uygulama veri arka ucu, tablolarının yanı sıra files özelliği üzerinden erişilen özel bir nesne depolama alanı edinir. Bunu görüntüler, PDF’ler, kamera kareleri, firmware blob’ları — kısacası bir tablo satırına ait olmayan her şey — için kullanın. Kurulum gerekmez: veri şablonunda files: bölümü bulunmayan bir uygulama bile default adında bir ad alanı edinir.

Temel fikir şudur: bir nesneyi sakladığınızda size aynı çağrıda doğrudan bir tablo sütununa yazabileceğiniz kalıcı bir URL döner; böylece bir pano widget’ı onu başka hiçbir iş yapmadan görüntüleyebilir:

# Store an object and get a permanent URL back in the same call info = await ironflock.files.put("part-1.jpg", jpeg_bytes, content_type="image/jpeg") # The URL is safe to store in a table column — a dashboard widget can then # render <img src="{{photo_url}}"> without any extra round trip await ironflock.publish_to_table("inspections", part_id="1", photo_url=info.url) # Read it back data = await ironflock.files.get("part-1.jpg") # Walk every object under a prefix (pages are fetched for you) async for obj in ironflock.files.iter(prefix="2026/"): print(obj.key, obj.size)

Bu URL hiçbir zaman sona ermez, ancak herkese açık bir bağlantı değildir: yalnızca bu veri arka ucu üzerinde READ erişimine sahip, kimliği doğrulanmış bir istek sahibi tarafından okunabilir kalır ve bir kimlik doğrulama proxy’si bunu her istekte yeniden denetler. Bu nedenle veritabanında saklanması güvenlidir.

Ad Alanları

Bir ad alanı (namespace), politika taşıyan bir anahtar önekidir — saklama süresi, paylaşım kuralları, izin verilen içerik türleri. Ayrı bir bucket değildir; bir uygulamanın her ad alanı, o uygulamanın tek depolama alanının içinde yer alır. Yalnızca bir nesne kümesinin farklı kurallara ihtiyacı olduğunda yeni bir tane tanımlayın; aksi halde default içinde kalın ve nesnelerinizi 2026/03/part-1.jpg gibi anahtar yollarıyla düzenleyin.

Ek ad alanlarını data-template.yml dosyasında tanımlayın:

files: # Storage budget the app suggests for itself. The project user can change it, # and their setting is the one that gets enforced. quotaBytes: 5368709120 namespaces: - name: frames description: Raw camera frames, one JPEG per inspected part. contentTypes: ["image/jpeg"] maxObjectBytes: 20971520 retention: { deleteAfter: 30 days }

Bütçenin ad alanı başına değil, uygulamanın tamamı için bir kez tanımlandığına dikkat edin. Bir ad alanı yalnızca uygulamanın tek depolama alanı içindeki bir anahtar önekidir, dolayısıyla önek başına bir bütçenin uygulanabileceği bir şey yoktur. maxObjectBytes ise ad alanı başınadır — bir toplamı değil, tek bir nesneyi sınırlar.

Aşağıdaki her metot ad alanını isteğe bağlı bir argüman olarak alır ve varsayılan olarak default kullanır.

Nesneleri Saklama ve Okuma

# Bytes in, bytes out info = await ironflock.files.put("reports/march.pdf", pdf_bytes, content_type="application/pdf") data = await ironflock.files.get("reports/march.pdf") # Or straight from/to a local file — these stream on the large-object path, # so a multi-gigabyte file never has to fit in memory await ironflock.files.put_file("firmware/v2.bin", "/data/build/v2.bin") await ironflock.files.get_to_file("firmware/v2.bin", "/tmp/v2.bin")
MetotAçıklama
put(key, data, …)Bir nesneyi saklar (Python’da bytes, JavaScript’te Uint8Array). Nesnenin url değeri dahil meta verilerini döndürür
get(key, namespace?)Nesnenin içeriğini döndürür
put_file(key, path, …) / get_to_file(key, path, …)Yalnızca Python. Yerel bir dosyadan saklar ya da yerel bir dosyaya yazar. Büyük nesne yolunda akış (stream) olarak aktarır
delete(key, namespace?)Bir nesneyi siler
copy(key, to, …)Bir nesneyi, isteğe bağlı olarak başka bir ad alanına kopyalar
move(key, to, …)Önce kopyalar, sonra siler. Atomik değildir — serviste bir taşıma fiili yoktur, bu nedenle başarısız bir silme her iki kopyayı da bırakır

JavaScript’te dosya yolu yardımcıları yoktur, çünkü paket hem Node hem de tarayıcı için tek bir derleme yayımlar — yerel dosyaları fs ile kendiniz okuyup yazın.

put şunları kabul eder: content_type / contentType (MIME türü; ad alanı hangilerine izin verildiğini kısıtlayabilir) ve namespace. Python’da bunlar anahtar kelime argümanlarıdır; JavaScript’te bir seçenekler nesnesinin içine girer.

Listeleme ve İnceleme

MetotAçıklama
list(…)Nesnelerin tek bir sayfası. objects, prefixes, is_truncated / isTruncated ve sonraki sayfa için geri geçirilecek bir cursor döndürür
iter(…) / iterate(…)Bir önek altındaki her nesne üzerinde, sayfalamayı otomatik yaparak ilerleyen asenkron yineleyici. Python’da iter, JavaScript’te iterate olarak adlandırılır
stat(key, namespace?)İçeriğini aktarmadan tek bir nesnenin meta verileri
exists(key, namespace?)Bir nesnenin var olup olmadığı
namespaces()Bu uygulamanın kullanabileceği ad alanları
usage(…)Uygulamanın ne kadar depolama alanı kullandığı — aşağıya bakın
catalog()Ad alanları ile sunucunun bildirdiği limitler ve kotalar. İlk çağrıdan sonra önbelleğe alınır

Nesneler her iki SDK’da da aynı alanlarla, her dilin adlandırma stiline uygun olarak tanımlanır: namespace, key, size, etag, content_type / contentType, last_modified / lastModified, checksum_sha256 / checksumSha256 ve url.

Depolama Kullanımı ve Kota

usage, tek bir çağrıyla doğrudan nesne deposundan yanıt alır; bu nedenle toplamlar SDK tarafından toplanmış değil, kesindir:

u = await ironflock.files.usage() print(u.size_bytes, u.object_count, u.quota_bytes, u.free_bytes) # Break the total down per namespace (costs one listing per namespace) detailed = await ironflock.files.usage(detail=True) print(detailed.per_namespace) # {"default": 1048576, "frames": 73400320}
AlanAnlamı
size_bytes / sizeBytesŞu anda saklanan bayt miktarı
object_count / objectCountSaklanan nesne sayısı
quota_bytes / quotaBytesUygulanan bütçe. 0 sınırsız anlamına gelir
free_bytes / freeBytesKalan bayt miktarı. -1 sınırsız anlamına gelir — burada 0 bildirmek “dolu” gibi okunurdu
per_namespace / perNamespaceAd alanı başına bayt miktarı. Yalnızca ayrıntılı dökümü istediğinizde bulunur

Ad alanı başına döküm varsayılan olarak kapalıdır, çünkü depo bunu doğrudan yanıtlayamaz: hesabı depolama alanı başına tutar ve bir ad alanı yalnızca bir önektir, dolayısıyla SDK’nın boyutları toplamak için her ad alanını listelemesi gerekir. Bunu istediğinizde isteyin, sıcak bir kod yolunda değil.

Birbirinden ayrı tutulması gereken iki farklı kota vardır. catalog() her ikisini de bildirir:

AlanAnlamı
quota_bytes / quotaBytesGerçekte uygulanan değer; nesne deposundan okunur — proje kullanıcısının ayarı
suggested_quota_bytes / suggestedQuotaBytesUygulamanın veri şablonunun istediği değer. Hiçbir şey istemediyse 0

Bir kullanıcı uygulamanın bütçesini yükselttiğinde ya da düşürdüğünde bu iki değer birbirinden ayrılır; uygulanan değerin şablondan değil depodan okunmasının nedeni de budur — uygulamanın yeniden dağıtılması, kullanıcının seçimini sessizce sıfırlamamalıdır. Bir arayüz her ikisini de gösterebilir (“uygulama X öneriyor, siz Y ayarladınız”). Uygulama her zaman ilkini kullanır.

Nesneleri Paylaşma

İki tür bağlantı vardır ve aradaki fark önemlidir:

MetotÖmürKimler okuyabilir
url(key, …)KalıcıYalnızca bu veri arka ucu üzerinde READ yetkisine sahip, kimliği doğrulanmış bir istek sahibi — her istekte yeniden denetlenir. Bir tablo sütununda saklanması güvenlidir
share_url / shareUrlSüreli (varsayılan 15 dakika, sunucu tarafından sınırlanır)Bağlantıyı elinde tutan herkes. Kullanıldığında yetkilendirmeyi yeniden denetleyen hiçbir şey yoktur

share_url / shareUrl bir taşıyıcı (bearer) yetkidir: geçici erişime ihtiyacı olan bir kişiye verin ve veritabanında saklamayın. Bir panonun görüntülediği her şey için url kullanın.

url, dağıtımın bir HTTP kenarı bulunmadığı durumlarda (örneğin düz HTTP çalışan bir appliance) None / undefined döndürür — bu, get’e geri dönmeniz gerektiğinin işaretidir. Nesnenin etag değerini version argümanı olarak geçmek, tarayıcıların yanıtı değişmez (immutable) biçimde önbelleğe almasını sağlar.

upload_url / uploadUrl, doğrudan yükleme kabul eden süreli bir URL üretir ve url, method, headers ile expires_in / expiresIn döndürür. Tam olarak döndürdüğü başlıkları gönderin, aksi halde imza doğrulanmaz.

Büyük Nesneler

SDK aktarım yolunu boyuta göre otomatik olarak seçer — yapılandırılacak bir şey yoktur:

Nesne boyutuNasıl aktarılır
Satır içi limite kadar (şu anda 6 MiB)Mesaj yönlendiricisi üzerinden tek bir çağrı
Daha büyükYönlendiriciyi atlayarak, HTTPS üzerinden doğrudan nesne depolamaya

Kesin limit, sunucu tarafından çalışma zamanında catalog() içinde inline_max_bytes / inlineMaxBytes olarak bildirilir; böylece yeni bir SDK sürümü çıkmadan yükseltilebilir.

Geriye iki tavan kalır ve her ikisi de hangisine takıldığınızı belirten bir nedenle TOO_LARGE bildirir:

  • 5 GiB — nesne deposunun tek seferlik yükleme limiti. Çok parçalı (multipart) yükleme henüz uygulanmadı.
  • Doğrudan uç noktanın bulunmadığı yerlerde satır içi limit — hava boşluklu (air-gapped) bir appliance büyük bir nesneyi hiç aktaramaz. Hiçbir yeniden deneme ya da daha küçük parça işe yaramaz ve mesaj bunu açıkça söyler.

Doğrudan yol, cihazın yalnızca yönlendiriciye değil, nesne depolama sunucusuna da erişebilmesini gerektirir. Sahada sık görülen iki arıza, yetkilendirme sorunu gibi görünmek yerine kendi kodlarını alır: PRESIGN_UNREACHABLE (yalnızca yönlendiriciye izin veren bir proxy) ve CLOCK_SKEW (nesne deposu, 15 dakikadan fazla sapmış istekleri reddeder — cihazdaki NTP’yi kontrol edin).

Dosya Depolama Hataları

Her dosya işlemi, kararlı bir code ve insan tarafından okunabilir bir reason taşıyan bir FileStoreError yükseltir (Python) / fırlatır (JavaScript). reason üzerinde değil, her zaman code üzerinde dallanın.

from ironflock.filestore import FileStoreError try: await ironflock.files.put("huge.bin", payload) except FileStoreError as e: if e.code == "QUOTA_EXCEEDED": print("Filestore is full:", e.reason) else: raise
KodAnlamı
NOT_AUTHORIZEDÇağıran taraf bu işlemi gerçekleştiremez
NO_SUCH_NAMESPACEAd alanı veri şablonunda tanımlı değil
NO_SUCH_OBJECTAnahtar mevcut değil
TOO_LARGETek çağrılık aktarım limitini aşıyor
OBJECT_TOO_LARGEAd alanının kendi maxObjectBytes değerini aşıyor
QUOTA_EXCEEDEDDosya deposu dolu
CONTENT_TYPE_NOT_ALLOWEDAd alanı contentTypes değerini kısıtlıyor
NOT_SUPPORTEDArka uç bunu yapamıyor
NOT_AVAILABLEBu dağıtımda dosya servisi yok
PRESIGN_UNREACHABLENesne depolamaya doğrudan erişilemiyor (bir proxy mi?)
CLOCK_SKEWCihaz saati fazlaca sapmış
INTERNALBunların dışındaki her şey

Daha yeni bir sunucu, bu SDK sürümünün bilmediği kodlar sunabilir. Bunlar tek bir kategoriye indirgenmeden code olarak geçirilir; bu nedenle tanınmayan bir değeri genel bir hata olarak ele alın.

Python’da FileStoreError, ironflock.filestore içinden içe aktarılır; JavaScript’te ise paket kökünden dışa aktarılır (import { FileStoreError } from "ironflock").

Cihazlar Arası İletişim

registerDeviceFunction / register_device_function

Aynı projedeki diğer cihazların çağırabiledği bir prosedür kaydeder. SDK, prosedürü mevcut cihaza otomatik olarak ad alanı ataştırır.

def add(a, b): return a + b await ironflock.register_device_function("com.myapp.add", add)

register(), register_device_function() için bir takma addır.

callDeviceFunction / call_device_function

Başka bir cihaz tarafından kaydedilmiş bir prosedürü çağırır. SDK, hedef cihazın anahtarını kullanarak tam WAMP konusunu otomatik olarak oluşturur.

result = await ironflock.call_device_function( 42, # target device key "com.myapp.add", # procedure name args=[3, 5] # arguments ) print(result) # 8

call

Tam bir WAMP URI kullanarak uzak prosedür çağırır. Tam konuyu bildiğinizde doğrudan çağrılar için bunu kullanın.

result = await ironflock.call("some.full.wamp.topic", args=[42])

Cihaz Meta Verisi

setDeviceLocation / set_device_location

Cihazın GPS konumunu platformda günceller. Değişiklikler IronFlock haritalarda gerçek zamanlı olarak yansıtılır.

await ironflock.set_device_location(long=8.6821, lat=50.1109)
ParametreAralık
long-180 ile 180
lat-90 ile 90

Konum geçmişi saklanmaz. Konumu zaman içinde takip etmek için ayrı bir tablo oluşturun ve publish_to_table / publishToTable kullanın.

getRemoteAccessUrlForPort

Cihazın belirtilen portu için genel uzaktan erişim URL’sini döndürür.

url = ironflock.getRemoteAccessUrlForPort(8080) # "https://<device_key>-<app_name>-8080.app.ironflock.com"

Bağlantı Özellikleri & Yaşam Döngüsü

ÖzellikTürAçıklama
is_connectedboolPlatform bağlantısının aktif olup olmadığı
connectionCrossbarConnectionAltta yatan bağlantı örneği (gelişmiş kullanım)
MetotAçıklama
run()Bağlantıyı başlatır ve mainFunc’ı çalıştırır (engelleme)
await start()Bağlantıyı asenkron olarak başlatır
await stop()Bağlantıyı durdurur ve çalışan görevleri iptal eder
await run_async()Bağlantıyı başlatır ve asenkron olarak çalıştırmaya devam eder

Hata Yönetimi

Her SDK metodu hatayı açıkça bildirir: geçersiz argümanlarda, kopan bir bağlantıda veya platformdan gelen bir reddetmede, işlemi, konuyu ve nedeni belirten bir mesajla bir istisna yükseltir (Python) ya da reddeder (JavaScript). Hiçbir şey sessizce yutulmaz; bu nedenle hayatta kalmasını istediğiniz çağrıları bir try bloğuna sarın.

try: rows = await ironflock.getHistory("sensordata", {"limit": 100}) except ValueError as e: # Invalid parameters — e.g. limit out of range, or a malformed filter print(f"Bad query: {e}") except RuntimeError as e: # Not connected, table not in the data-template, or the platform rejected the call print(f"Query failed: {e}")

JavaScript’te platformdan kaynaklanan hatalar WampError örnekleridir — ek olarak WAMP hata URI’sini error içinde, hata yükünü ise args / kwargs içinde taşıyan normal bir Error alt sınıfı. Bunun dışındaki her şey (hatalı parametreler, bağlantı olmaması) düz bir Error’dır.

Yükseltme: Eski SDK sürümleri bir çağrı başarısız olduğunda bir mesaj kaydedip None / null döndürüyordu. Artık bunun yerine hata yükseltiyorlar; bu nedenle if result is None: biçimindeki kodlar hataları artık yakalamaz — try / except (ya da try / catch) kullanın.

Tarayıcı Kullanımı (Yalnızca JavaScript)

JavaScript SDK modern tarayıcılarda çalışır. Tarayıcılarda ortam değişkenleri bulunmadığından, tüm yapılandırmayı yapıcı aracılığıyla geçin:

import { IronFlock } from "ironflock"; const ironflock = new IronFlock({ serialNumber: "device-serial-from-server", deviceKey: "my-device-key", appName: "MyWebApp", swarmKey: 10, appKey: 20, env: "PROD", }); await ironflock.start(); await ironflock.publishToTable("sensordata", [{ temperature: 22 }]);

Kimlik bilgilerini sabit kodlamak yerine arka ucunuzdan yapılandırma almak için IronFlock.fromServer()’ı kullanın:

const ironflock = await IronFlock.fromServer("/api/ironflock-config"); await ironflock.start();

Arka uç uç noktanız, bağlantı seçenekleriyle (serialNumber, deviceKey, appName, swarmKey, appKey, env) bir JSON nesnesi döndürmelidir.

AI Ajan Fonksiyonlarını Kaydetme

SDK, AI ajanları tarafından çağrılabilecek fonksiyonlar kaydedebilir. Bir prosedür kaydedin ve ai-template.yml dosyanızdaki konusunu referans alın:

def get_sensor_reading(sensor_id): """Returns the latest reading from a sensor.""" reading = read_from_hardware(sensor_id) return { "sensor_id": sensor_id, "temperature": reading.temp, "humidity": reading.hum, "timestamp": reading.ts } await ironflock.register_device_function("sensors.get_latest", get_sensor_reading)

AI ajanı, kullanıcı canlı sensör verisi gerektiren bir soru sorduğunda bu fonksiyonu çağırabilir.

Kayıtlı WAMP konusunu bir AI ajanına bağlamak için, uygulamanızın .ironflock/ai-template.yml dosyasında referans alın:

sensor_agent: tool_description: | Delegate to this agent when the user asks about sensor readings, live device data, or current environmental conditions. system_prompt: | You are a sensor data specialist. Use get_current to retrieve the latest reading from any sensor. Always include the unit in your response. main: true max_context_tokens: 30000 max_iterations: 5 tools: get_current: description: Returns the latest reading from a sensor. topic: sensors.get_latest parameters: sensor_id: type: string description: The sensor identifier to query. required: true

topic değeri (sensors.get_latest), edge kodunuzdaki register_device_function / registerDeviceFunction’ına geçirilen adla eşleşmelidir. IronFlock, çağrıyı otomatik olarak fonksiyonun kaydedildiği cihaza yönlendirir.

Tam ai-template.yml referansı için bkz. Ajan & Araç Tanımlama.

Ortam Değişkenleri

Bu değişkenler IronFlock runtime tarafından uygulama container’ı içinde otomatik olarak ayarlanır:

DeğişkenAçıklama
DEVICE_NAMECihaz görüntülenme adı
DEVICE_SERIAL_NUMBERBenzersiz, değişmez cihaz tanımlayıcısı
DEVICE_KEYKimlik doğrulama için cihaz anahtarı
SWARM_KEYProje tanımlayıcısı
APP_KEYUygulama tanımlayıcısı
APP_NAMEUygulama adı
ENVOrtam: DEV veya PROD
import os device_name = os.environ.get("DEVICE_NAME") serial = os.environ.get("DEVICE_SERIAL_NUMBER") project_key = os.environ.get("SWARM_KEY")
Last updated on