Zbuduj swoją pierwszą aplikację
Ten przewodnik prowadzi przez typowy przepływ pracy budowania aplikacji IronFlock, która zbiera dane z urządzeń brzegowych i wyświetla je na panelach w czasie rzeczywistym. Na końcu będziesz mieć model danych, logikę brzegową, formularz konfiguracyjny dla użytkowników i wykresy na żywo — wszystko połączone przez bazę danych projektu.
1. Zaprojektuj model danych
Zacznij w pliku .ironflock/data-template.yml. Pomyśl o dwóch kategoriach tabel:
- Tabele encji — śledzą aktualny stan rzeczy (urządzeń, maszyn, połączeń). Wiersze są dołączane przy każdej zmianie;
maintainLatestFlagFordeklaruje, które kolumny identyfikują encję, dzięki czemu najnowszy wiersz każdej encji można odczytać na żądanie. - Tabele szeregów czasowych — zbierają pomiary w czasie (odczyty czujników, metryki). Każdy wiersz to nowy punkt danych ze znacznikiem czasu.
data:
tables:
# Tabela encji: jeden wiersz per urządzenie, aktualny stan zawsze dostępny
- tablename: devices
maintainLatestFlagFor: ['device_key']
columns:
- id: tsp
dataType: timestamp
- id: device_key
dataType: string
- id: status
dataType: string
- id: device_name
dataType: string
- id: deleted
dataType: boolean
# Tabela encji: serwery Modbus skonfigurowane przez użytkownika
- tablename: modbus_servers
maintainLatestFlagFor: ['server_id']
columns:
- id: tsp
dataType: timestamp
- id: server_id
dataType: string
- id: host
dataType: string
- id: port
dataType: numeric
- id: deleted
dataType: boolean
# Tabela szeregów czasowych: okresowe odczyty z podłączonego sprzętu
- tablename: readings
columns:
- id: tsp
dataType: timestamp
- id: server_id
dataType: string
- id: metric
dataType: string
- id: value
dataType: numeric2. Skonfiguruj środowisko testowe
Aby testować swoją aplikację, potrzebujesz środowiska deweloperskiego w projekcie z co najmniej jednym urządzeniem online:
- Kliknij Develop na stronie szczegółów aplikacji, aby otworzyć Cloud IDE.
- Wybierz urządzenie online z dowolnego projektu, do którego masz dostęp.
- Kliknij Create Backend w panelu bocznym, aby stworzyć środowisko deweloperskie w bazie danych tego projektu.
To tworzy instancje tabel zdefiniowanych w data-template.yml w bazie danych projektu. Możesz je przejrzeć w widoku Fleet Database projektu.
Cloud IDE zapewnia pełne środowisko VS Code z eksploratorem plików, edytorem, terminalem i panelem Edge Development do budowania aplikacji i wdrażania jej na urządzenie.
3. Napisz kod brzegowy
Twój kontener Docker działa na urządzeniu i używa SDK IronFlock do interakcji z bazą danych projektu.
Rejestruj urządzenie przy uruchomieniu
Gdy komponent brzegowy się uruchamia, dołącz wiersz do tabeli encji devices, aby panel wiedział, że urządzenie jest online:
Python
import asyncio
import os
from datetime import datetime, timezone
from ironflock import IronFlock
async def main():
# Zarejestruj to urządzenie jako online
await flock.append_to_table("devices", {
"device_key": os.environ.get('DEVICE_KEY'),
"tsp": datetime.now(timezone.utc).isoformat(),
"status": "online",
"device_name": os.environ.get('DEVICE_NAME'),
"deleted": False
})
# ... reszta twojej logiki
flock = IronFlock(mainFunc=main)
flock.run()Ponieważ devices używa maintainLatestFlagFor: ['device_key'], poprzedni wiersz statusu tego urządzenia jest automatycznie zastępowany. Widgety z włączonym filtrem latest zawsze pokazują aktualny stan.
Reaguj na konfigurację użytkownika
Użytkownicy mogą dodawać serwery Modbus przez formularz na panelu (zobacz krok 4). Twój kod brzegowy subskrybuje tabelę modbus_servers i reaguje na nowe wpisy:
Python
async def main():
# ... rejestracja urządzenia ...
# Odczytaj istniejące serwery Modbus
existing = await flock.getHistory("modbus_servers", {
"limit": 1000,
"filterAnd": [
# "latest": True zwraca tylko najnowszy wiersz dla każdego server_id
{"latest": True},
# deleted IS NULL OR deleted = false
{"combinator": "OR", "filters": [
{"column": "deleted", "operator": "IS NULL"},
{"column": "deleted", "operator": "=", "value": False}
]}
]
})
for server in existing:
create_modbus_connection(server)
# Reaguj na nowe serwery w czasie rzeczywistym
def on_server_change(*args, **kwargs):
server = args[0] if args else kwargs
if server.get("deleted"):
delete_modbus_connection(server["server_id"])
else:
create_modbus_connection(server)
await flock.subscribe_to_table("modbus_servers", on_server_change)Zbieraj dane szeregów czasowych
Po nawiązaniu połączenia Modbus okresowo wykonuj polling i zapisuj odczyty do tabeli readings:
Python
async def modbus_poll_loop(server_id, client):
while True:
values = client.read_registers()
tsp = datetime.now(timezone.utc).isoformat()
for metric, value in values.items():
await flock.publish_to_table("readings", {
"tsp": tsp,
"server_id": server_id,
"metric": metric,
"value": value
})
await asyncio.sleep(5)Każdy wiersz potrzebuje znacznika czasu tsp: backend danych po cichu odrzuca opublikowany wiersz bez niego, zostawiając jedynie wpis w tabeli error-logs aplikacji.
4. Zbuduj panel
Otwórz edytor paneli i dodaj widgety połączone z tabelami backendu danych.
Pokaż status urządzenia
Dodaj widget Tabela połączony z tabelą devices. Włącz przełącznik latest w ustawieniach filtrów widgetu, aby zawsze pokazywał aktualny stan każdego urządzenia. Tabela aktualizuje się automatycznie, gdy urządzenie przechodzi w stan online lub offline.
Pozwól użytkownikom konfigurować serwery Modbus
Dodaj widget Formularz połączony z tabelą modbus_servers. Skonfiguruj pola dla host i port. Gdy użytkownik wypełni i wyśle formularz, nowy wiersz zostaje automatycznie wstawiony do tabeli modbus_servers — obsługa wysłania formularza nie wymaga żadnego kodu backendu.
Twój kod brzegowy odbiera nowy wiersz przez subscribeToTable (zobacz krok 3) i nawiązuje połączenie Modbus.
Wizualizuj dane szeregów czasowych
Dodaj widget Wykres liniowy połączony z tabelą readings. Ustaw oś X na kolumnę tsp i oś Y na value. Wykres aktualizuje się w czasie rzeczywistym, gdy z urządzeń napływają nowe odczyty — bez odpytywania ani ręcznego odświeżania.
Jak to wszystko się łączy
┌─────────────────────────────────────────────────────────┐
│ Board (Dashboard) │
│ ┌──────────┐ ┌──────────────┐ ┌───────────────────┐ │
│ │ Table │ │ Form │ │ Line Chart │ │
│ │ devices │ │ modbus_servers │ │ readings │ │
│ └────┬─────┘ └──────┬───────┘ └────────┬──────────┘ │
│ │ │ │ │
└───────┼───────────────┼───────────────────┼─────────────┘
│ │ │
┌────▼───────────────▼───────────────────▼────┐
│ Project Database │
│ devices │ modbus_servers │ readings │
└────▲───────────────▲───────────────────▲────┘
│ │ │
┌────┴───────────────┴───────────────────┴────┐
│ Edge Code (on device) │
│ register device → read config → poll data │
└─────────────────────────────────────────────┘Baza danych projektu jest jedynym źródłem prawdy. Kod brzegowy do niej zapisuje, panel odczytuje z niej dane w czasie rzeczywistym, a działania użytkowników w formularzach zapisują do niej dane z powrotem. Twój kod brzegowy może subskrybować te zmiany, aby zamknąć pętlę — bez własnych endpointów API.
Wskazówki
- Zacznij od tabel encji. Uruchom rejestrację urządzeń i tabelę statusu, zanim dodasz zbieranie szeregów czasowych.
- Używaj
maintainLatestFlagForw każdej tabeli, w której musisz odpytywać aktualny stan. Pozwala dołączać historię i odczytywać najnowszy wiersz każdej encji — przełącznikiem latest w widgecie lub wpisem{"latest": true}w filtrze SDK (ironflock.Latest()w Go) — bez dodatkowego kodu. - Dodaj kolumnę
deleteddo tabel encji, którymi użytkownicy zarządzają przez formularze, aby rekordy można było usuwać miękko z zachowaniem historii. - Używaj
appendToTabledo zapisów wymagających potwierdzenia (np. początkowej rejestracji urządzenia). UżywajpublishToTabledo telemetrii o wysokiej częstotliwości, gdzie tryb „wyślij i zapomnij” jest akceptowalny. - Utrzymuj tabele szeregów czasowych w prostej formie. Jeden znacznik czasu, identyfikator źródła i zmierzone wartości. Do agregacji używaj tabel transformacyjnych.
Następne kroki
Jeśli twój sprzęt udostępnia webowy interfejs HMI lub interfejs konfiguracyjny, możesz osadzić go bezpośrednio w panelu IronFlock za pomocą widgetu Osadź i tuneli urządzenia. Szczegóły znajdziesz w przewodniku Osadzanie zewnętrznych interfejsów HMI.