HTTP-/MOTORSENSE-Treiber
Überblick
Zwei Betriebsarten auf Basis des HTTP-Protokolls:
HTTP— Wenn ein externes System Werte per/api/v1/tag/{tagId}/valueoder/api/httppusht, werden sie im internen Cache des Edge (current_value_map) gebunden. Bei jedem Erfassungszyklus wird aus dem Cache gelesen.MOTOR_SENSE— Die KOPENS Motor Sense API wird gepollt, um Signal- und Zustandsdaten zu erfassen. Eine separateplantpulse-edge-driver-motorsensor.jarwird per Reflection geladen.
| Punkt | HTTP | MOTOR_SENSE |
|---|---|---|
opc_type | HTTP | MOTOR_SENSE |
| Implementierungsklasse | plantpulse.driver.protocol.http.HTTPDriver | plantpulse.driver.protocol.motor_sense.MotorSenseDriver (separates jar) |
| read | ✅ (Cache) | ✅ (HTTP-Polling) |
| write | ✅ (bind()) | ❌ |
| Sicherheit | keine (bei Authentifizierung auf REST-Ebene Proxy erforderlich) | API Key + customer-id |
HTTP-Modus
OPC-Registrierungsformular
| Feld | Bedeutung | Beispiel |
|---|---|---|
opc_agent_ip | (tatsächlich ungenutzt, nur zur Identifikation) | 127.0.0.1 |
opc_agent_port | (tatsächlich ungenutzt) | 0 |
timecycle | Cache-Lesezyklus (ms) | 1000 |
Format von Tag plc_address
Freie Schlüsselzeichenkette. Entspricht 1:1 dem io_address von bind(io_address, value).
| Notation | Bedeutung |
|---|---|
temperature | Von extern per bind("temperature", "25.7") eingegangener Wert |
line/A/rpm | Freie Zeichenkette inklusive Schrägstrichen möglich |
Werte schreiben (POST /api/v1/tag/{tagId}/value)
curl -X POST http://<edge-host>/api/v1/tag/OPC_HTTP_TAG_00001/value \
-H "Content-Type: application/json" \
-d '{ "value": "42.5" }'
Intern wird HTTPDriver.bind(plc_address, "42.5") aufgerufen → im nächsten Polling-Zyklus wird dieser Wert gelesen.
curl-Registrierungsbeispiel (HTTP)
curl -X POST http://<edge-host>/api/v1/opc \
-H "Content-Type: application/json" \
-d '{
"opc_id": "OPC_HTTP_BIND",
"opc_type": "HTTP",
"opc_name": "External HTTP Bind",
"opc_agent_ip": "127.0.0.1",
"opc_agent_port": "0",
"site_id": "SITE_00001",
"auto_collect": true,
"timecycle": 1000,
"tag_list": [
{
"tag_id": "OPC_HTTP_BIND_TAG_00001",
"tag_name": "ExtTemp",
"plc_address": "temperature",
"data_type": "Float"
}
]
}'
MOTOR_SENSE-Modus
Merkmale
- Keine Eingabe von IP / Port erforderlich (HTTP-Protokoll; im Registrierungsformular wird jedoch automatisch die IP/der Port des OPC-Agenten eingetragen)
- Keine manuelle Eingabe von Tag-Informationen erforderlich — automatische Erzeugung (
signals,health_index, 2 Stück) - Datenerfassung im JSON-Format
- Anzeige der Daten gruppiert nach ASSET
OPC-Registrierungsformular
| Feld | Bedeutung | Speicherort |
|---|---|---|
| API KEY | Authentifizierungsschlüssel der Motor Sense API | options.api-key |
| Kunden-ID | Kundenkennung | options.customer-id |
| Asset-Listen-URL | URL zum Abruf der Asset-Liste | options.asset-list-url |
| Asset-Signal-URL | URL der Asset-Signaldaten | options.asset-signal-url |
| Asset-Zustandsindex-URL | URL des Asset-Zustandsindex | options.asset-status-url |
| Wellenform/Spektrum laden | Ob Wellenform-/Spektrumdaten geladen werden | options.load-waveform-spectrum (optional) |
Die URL muss mit http:// oder https:// beginnen (Prüfung auf JS-Ebene).
Automatisch erzeugte Tags
tag_id | tag_name | plc_address | data_type |
|---|---|---|---|
<OPC_ID>_TAG_00001 | signals | signals | String |
<OPC_ID>_TAG_00002 | health_index | health_index | String |
VALUE wird als JSON-Array-String gespeichert (mehrere ASSET-Daten in einem Tag).
signals VALUE-Beispiel
[
{
"asset_id": "4d4c097f-4449-4cf0-a7ec-b770e3950e00",
"sensor_number": "1300",
"created_at": 1768376660,
"temperature": 25.7,
"voltage": 3.31,
"rms_x": 0.1733,
"rms_y": 0.4156,
"rms_z": 0.4697,
"rms_xyz": 0.5476
}
]
health_index VALUE-Beispiel
[
{
"asset_id": "4d4c097f-4449-4cf0-a7ec-b770e3950e2a",
"time": "2021-12-21",
"imbalance_health": 0.98,
"misalignment_health": 1.0,
"looseness_health": 1.0,
"bearing_health": 1.0,
"asset_health": 0.99
}
]
curl-Registrierungsbeispiel (MOTOR_SENSE)
curl -X POST http://<edge-host>/api/v1/opc \
-H "Content-Type: application/json" \
-d '{
"opc_id": "OPC_MS_PLANT_A",
"opc_type": "MOTOR_SENSE",
"opc_name": "Motor Sense Plant A",
"opc_agent_ip": "127.0.0.1",
"opc_agent_port": "0",
"site_id": "SITE_00001",
"auto_collect": true,
"timecycle": 1000,
"options": {
"api-key": "YOUR_API_KEY",
"customer-id": "kopens-001",
"asset-list-url": "https://api.example.com/assets",
"asset-signal-url": "https://api.example.com/signals",
"asset-status-url": "https://api.example.com/health",
"load-waveform-spectrum": "false"
},
"tag_list": [
{
"tag_id": "OPC_MS_PLANT_A_TAG_00001",
"tag_name": "signals",
"plc_address": "signals",
"data_type": "String",
"description": "에셋의 시그널 데이터"
},
{
"tag_id": "OPC_MS_PLANT_A_TAG_00002",
"tag_name": "health_index",
"plc_address": "health_index",
"data_type": "String",
"description": "에셋의 상태 지수"
}
]
}'
Verhaltensunterschiede speziell bei MOTOR_SENSE
| Normale PLC | MOTOR_SENSE |
|---|---|
Ist isConnected() gleich false, wird read übersprungen | read wird auch bei isConnected()=false versucht (bei HTTP sind kurzzeitige Unterbrechungen häufig) |
| Anzeige der normalen TAG-Tabelle im Bildschirm | Anzeige als Karte je ASSET (HEALTH INDEX / SIGNAL) |
| Aktualisierung = Bildschirm-Reload | Hintergrundaktualisierung im 1-Sekunden-Takt (ohne Ladeanzeige) |
Häufige Fehler + Lösungen
| Meldung / Symptom | Ursache | Lösung |
|---|---|---|
MOTOR_SENSE 드라이버를 사용하려면 plantpulse-edge-driver-motorsensor.jar를 classpath에 추가 | separates jar nicht installiert | jar in WebContent/WEB-INF/lib/ ablegen und erneut deployen |
401 Unauthorized (Motor Sense) | Fehler bei API KEY / customer-id | Den von KOPENS ausgestellten korrekten Schlüssel verwenden. Auch den URL-Endpoint prüfen |
value im HTTP-Modus stets leer | Kein Aufruf von bind() oder Abweichung zwischen plc_address und io_address | Per POST /api/v1/tag/{tagId}/value pushen und den nächsten Zyklus abwarten |
tag write not supported for opc_type=... | write-Aufruf auf ein anderes Protokoll als HTTP | write ist nur bei Tags mit HTTP-Protokoll möglich. Siehe nachfolgende Phase 3 |
Beispielsammlung (nach Datentyp, HTTP-Modus)
Der HTTP-Modus übernimmt die von externen Systemen gepushten freien Zeichenkettenwerte unverändert. raw ist ein String, data_type / fomula werden zur Nachverarbeitung genutzt.
Boolean
data_type | plc_address | Push-Beispiel (POST /api/v1/tag/.../value) | Hinweis |
|---|---|---|---|
Boolean | pump1.run | {"value":"true"} | true/false-String |
Boolean | door.open | {"value":"1"} | 1/0 ebenfalls möglich (Casting bei Nachverarbeitung) |
Ganzzahl
data_type | plc_address | Push-Beispiel | Hinweis |
|---|---|---|---|
Integer | counter.production | {"value":"12345"} | |
Long | counter.total | {"value":"9876543210"} | über 32 Bit |
Gleitkomma
data_type | plc_address | Push-Beispiel | Hinweis |
|---|---|---|---|
Float | temperature | {"value":"25.7"} | |
Double | power.kw | {"value":"1234.56789"} | hohe Präzision |
Zeichenkette
data_type | plc_address | Push-Beispiel | Hinweis |
|---|---|---|---|
String | recipe.name | {"value":"R-2025-A"} | freie Zeichenkette |
String | barcode.last | {"value":"880699112"} | Push einer Barcode-Erfassung |
Einsatz von Formeln (HTTP)
| Zweck | data_type | fomula | Hinweis |
|---|---|---|---|
| Skalierung eines extern gepushten Werts | Float | ${VALUE}*1.8+32 | C → F |
| Summe zweier externer Werte | Float | ${VALUE}+${EXT_OFFSET} | Referenz auf ein anderes HTTP-Tag |
curl-Gesamtbeispiel (HTTP-Push-Ablauf)
# 1) OPC + 태그 등록
curl -X POST http://<edge-host>/api/v1/opc \
-H "Content-Type: application/json" \
-d '{
"opc_id": "OPC_HTTP_FULL",
"opc_type": "HTTP",
"opc_name": "External Bind Full",
"opc_agent_ip": "127.0.0.1",
"opc_agent_port": "0",
"site_id": "SITE_00001",
"auto_collect": true,
"timecycle": 1000,
"tag_list": [
{"tag_id":"OPC_HTTP_FULL_T01", "tag_name":"PumpRun", "plc_address":"pump1.run", "data_type":"Boolean"},
{"tag_id":"OPC_HTTP_FULL_T02", "tag_name":"Counter", "plc_address":"counter.prod", "data_type":"Integer"},
{"tag_id":"OPC_HTTP_FULL_T03", "tag_name":"TempC", "plc_address":"temperature", "data_type":"Float"},
{"tag_id":"OPC_HTTP_FULL_T04", "tag_name":"TempF", "plc_address":"temperature", "data_type":"Float", "fomula":"${VALUE}*1.8+32"},
{"tag_id":"OPC_HTTP_FULL_T05", "tag_name":"BatchName", "plc_address":"recipe.name", "data_type":"String"}
]
}'
# 2) 외부에서 값 push
curl -X POST http://<edge-host>/api/v1/tag/OPC_HTTP_FULL_T01/value \
-H "Content-Type: application/json" -d '{"value":"true"}'
curl -X POST http://<edge-host>/api/v1/tag/OPC_HTTP_FULL_T03/value \
-H "Content-Type: application/json" -d '{"value":"25.7"}'
# 3) 다음 polling 주기 후 조회
curl -s http://<edge-host>/api/v1/tag/OPC_HTTP_FULL_T03/value | jq
curl -s http://<edge-host>/api/v1/tag/OPC_HTTP_FULL_T04/value | jq # fomula 적용된 화씨값