תארו לעצמכם קו ייצור עם 500 חיישני רטט, טמפרטורה ולחץ. בכל שנייה — 250,000 דגימות. המפעיל לא יכול לעקוב אחרי הכל. הם צריכים אפליקציה ניידת שמציגה רק חריגות קריטיות. אנחנו בונים פתרונות כאלה — מאיסוף נתונים מ-PLC ועד התראות בסמארטפון. הניסיון שלנו: מעל 10 שנים באינטרנט התעשייתי של הדברים (IIoT), מעל 50 פרויקטים למפעלים. ללא ארכיטקטורה נכונה, האפליקציה טובעת בזרם הנתונים. לכן הצעד הראשון שלנו הוא תכנון מערכת איסוף ונירמול נתונים בשערי קצה (edge gateways), ולאחר מכן בניית ערוץ שידור אמין בזמן אמת.
ניטור נייד של ציוד תעשייתי: פתרונות טכניים מרכזיים
רכיב קצה לאיסוף נתונים
רכיב הקצה — שער תעשייתי (Moxa, Advantech, Siemens IPC) או שרת Linux מותאם — מנמאל נתונים מפרוטוקולים שונים ומפרסם סיכומים דרך MQTT או חושף אותם דרך REST/WebSocket. עבור האפליקציה הניידת, שני זרמים חשובים: זמן אמת — ערכים נוכחיים של פרמטרים מרכזיים, המעודכנים כל 1-5 שניות דרך WebSocket; והיסטוריה — מגמות על פני משמרת, יום, שבוע דרך REST API עם פגינציה ואגרגציה.
איך עובד איסוף נתונים בזמן אמת?
ברמת הציוד, הנתונים נאספים על ידי רכיב הקצה. הוא מנמאל נתונים מפרוטוקולים שונים (OPC-UA, Modbus, MQTT) ומפרסם סיכומים דרך MQTT או משרת אותם דרך REST/WebSocket.
Датчики → PLC / Edge Gateway → Time-Series DB (InfluxDB / TimescaleDB)
↓
Backend API (REST + WebSocket)
↓
Мобильное приложение אגרגציה ונירמול בשער הקצה
לפי תיעוד OPC-UA חלק 6, השער ממיר מרחב כתובות OPC-UA לתגיות שטוחות. עבור Modbus — מיפוי רישום לערך פיזי (לדוגמה, רישום 40001 = טמפרטורה עם מקדם 0.1). אגרגציה: ממוצע, מינימום, מקסימום על פני חלון של שנייה אחת. זה מפחית את התעבורה פי 10-100.
| פרוטוקול | יישום | תדירות דגימה | מורכבות אינטגרציה |
|---|---|---|---|
| OPC-UA | PLC, CNC | 1-1000 אלפיות השנייה | בינונית |
| Modbus RTU/TCP | חיישנים, בקרים | 10-1000 אלפיות השנייה | נמוכה |
| MQTT | התקני IoT | 1-60 שניות | נמוכה |
| Siemens S7 | SIMATIC S7 | 10-100 אלפיות השנייה | גבוהה |
למה ארכיטקטורת איסוף הנתונים היא האתגר המרכזי?
אנחנו משתמשים ב-Flutter עם WebSocket. לאמינות — חיבור מחדש אוטומטי עם backoff אקספוננציאלי.
class EquipmentMonitorRepository {
WebSocketChannel? _channel;
final StreamController<EquipmentState> _stateController = StreamController.broadcast();
Stream<EquipmentState> get stateStream => _stateController.stream;
void connect(String equipmentId, String token) {
_channel = WebSocketChannel.connect(
Uri.parse('wss://iiot.factory.com/ws/equipment/$equipmentId'),
);
_channel!.stream
.map((event) => json.decode(event as String))
.map(EquipmentState.fromJson)
.listen(
_stateController.add,
onError: _handleError,
onDone: _scheduleReconnect,
);
_channel!.sink.add(json.encode({'auth': token}));
}
void _scheduleReconnect() {
Future.delayed(const Duration(seconds: 5), () => connect(_lastId, _lastToken));
}
} דוגמה ליישום BLoC לניהול מצב
class EquipmentMonitorBloc extends Bloc<EquipmentEvent, EquipmentMonitorState> {
StreamSubscription<EquipmentState>? _subscription;
EquipmentMonitorBloc(this._repository) : super(EquipmentMonitorInitial()) {
on<StartMonitoring>((event, emit) async {
_subscription = _repository.stateStream.listen(
(state) => add(StateUpdated(state)),
);
_repository.connect(event.equipmentId, event.token);
});
on<StateUpdated>((event, emit) {
final current = event.state;
final isAlert = current.temperature > 85.0 || current.vibrationRms > 12.5;
emit(EquipmentMonitorRunning(state: current, hasAlert: isAlert));
});
}
}WebSocket מהיר פי 20 מ-HTTP polling למסירת טלמטריה. השוו:
| שיטה | השהיה | עומס סוללה | עומס שרת |
|---|---|---|---|
| HTTP polling | >1 שנייה | גבוה | גבוה |
| WebSocket | <100 אלפיות השנייה | נמוך | נמוך |
| gRPC-stream | <50 אלפיות השנייה | בינוני | בינוני |
ויזואליזציה של מגמות וחריגות
לנתונים היסטוריים אנחנו משתמשים ב-Датчики → PLC / Edge Gateway → Time-Series DB (InfluxDB / TimescaleDB) ↓ Backend API (REST + WebSocket) ↓ Мобильное приложение (Flutter) או class EquipmentMonitorRepository { WebSocketChannel? _channel; final StreamController<EquipmentState> _stateController = StreamController.broadcast(); Stream<EquipmentState> get stateStream => _stateController.stream; void connect(String equipmentId, String token) { _channel = WebSocketChannel.connect( Uri.parse('wss://iiot.factory.com/ws/equipment/$equipmentId'), ); _channel!.stream .map((event) => json.decode(event as String)) .map(EquipmentState.fromJson) .listen( _stateController.add, onError: _handleError, onDone: _scheduleReconnect, ); _channel!.sink.add(json.encode({'auth': token})); } void _scheduleReconnect() { Future.delayed(const Duration(seconds: 5), () => connect(_lastId, _lastToken)); } } . אופטימיזציה מרכזית: אגרגציה בצד ה-API. בקשה ל-InfluxDB-based API:
GET /api/v1/equipment/{id}/trend? parameter=temperature& from=2023-01-15T06:00:00Z& to=2023-01-15T18:00:00Z& resolution=300 # агрегация по 5 минут התשובה מחזירה מערך של 144 נקודות במקום 43,200. הגרף מצויר ללא פיגור.
קו בסיס וחריגות
תכונה שימושית היא הצגת קו הבסיס (טווח נורמלי) על הגרף. אם זרם המנוע בדרך כלל הוא 12-15A, הדגישו את האזור הזה כך שהמפעיל יראה מיד חריגה:
LineChartData buildTrendChart(List<TrendPoint> data, Range baseline) {
return LineChartData(
extraLinesData: ExtraLinesData(
horizontalLines: [
HorizontalLine(y: baseline.min, color: Colors.green.withOpacity(0.3)),
HorizontalLine(y: baseline.max, color: Colors.green.withOpacity(0.3)),
],
),
betweenBarsData: [
BetweenBarsData(
fromIndex: 0,
toIndex: 0,
color: Colors.green.withOpacity(0.1),
),
],
lineBarsData: [
LineChartBarData(
spots: data.map((p) => FlSpot(p.timestamp.toDouble(), p.value)).toList(),
color: data.any((p) => p.value > baseline.max || p.value < baseline.min) ? Colors.red : Colors.blue,
),
],
);
} מה צריך לקחת בחשבון במהלך הפיתוח?
- אגרגציית נתונים — אל תשדרו דגימות גולמיות, רק סיכומים.
- מצב לא מקוון — שמרו קריאות והתראות אחרונות במסד נתונים מקומי.
- הסלמה של התראות — אם המפעיל לא מאשר התראה תוך 5 דקות, הודיעו למפקח.
- אבטחה — TLS, JWT, הצפנה ברמת ההתקן.
- בדיקות — הדמיה של עד 10,000 התקנים.
כדי להפחית תעבורה, שער הקצה משתמש בחלון נע: מתוך 25,600 דגימות חיישן רטט, נוצרים 1-10 סיכומים — ממוצע, שיא, RMS, תדר יסודי.
שלבי פיתוח
- ביקורת מקורות נתונים — ניתוח פרוטוקולים ותדירות דגימה.
- עיצוב ארכיטקטורה — בחירת רכיב קצה ומסד נתונים מסוג Time-Series.
- פיתוח backend — API לאגרגציה, WebSocket, התראות.
- פיתוח אפליקציה ניידת — ממשק משתמש, מגמות, התראות push.
- אינטגרציה ובדיקות — על ציוד אמיתי.
- פריסה ותמיכה — App Store / Google Play, ניטור.
מה כלול?
- קוד מקור של האפליקציה הניידת (iOS/Android/Flutter).
- שירות backend עם API ו-WebSocket.
- תיעוד אינטגרציה ופריסה.
- גישה למאגר הקוד ול-CI/CD.
- הדרכת מפעילים (עד שעתיים).
- אחריות ל-6 חודשים על באגים.
עלות ולוח זמנים
פיתוח אפליקציה לסוג ציוד אחד עם WebSocket ומגמות אורך 4-8 שבועות. מחזור מלא כולל מצב לא מקוון והסלמה אורך 2-4 חודשים. התמחור הוא אישי לאחר ניתוח מקורות הנתונים שלכם. חיסכון טיפוסי מהטמעה מסתכם בכ-$9k–13k בשנה עקב הפחתת זמן השבתה ועלויות עצירות לא מתוכננות. צרו קשר לייעוץ עם מהנדס בנושא פיתוח נייד.







