View a markdown version of this page

Configurer des intégrations open source avec Docker (Linux) - AWS IoT SiteWise

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Configurer des intégrations open source avec Docker (Linux)

Pour rationaliser le processus de déploiement, vous pouvez utiliser Docker pour configurer Node-RED®, InfluxDB® et Grafana® dans un environnement Linux. Cette méthode utilise des conteneurs préconfigurés, ce qui permet un déploiement rapide et une gestion plus facile des composants.

Prérequis pour la configuration de Docker

Avant de commencer, vérifiez que vous disposez des éléments suivants :

Déployez les services

Ce déploiement exécute SiteWise Edge, InfluxDB et Grafana sur le même hôte. Node-RED

Configuration de l'environnement

  1. Accédez à un accès root :

    sudo -i
  2. Créez un fichier .env ou exportez les variables d'environnement suivantes :

    export INFLUXDB_PASSWORD=your-secure-influxdb-password export INFLUXDB_TOKEN=your-secure-influxdb-token export GRAFANA_PASSWORD=your-secure-grafana-password

Configurer le réseau Docker

  • Créez un réseau de ponts en utilisant ce nomSiteWiseEdgeNodeRedDemoNetwork.

    docker network create --driver=bridge SiteWiseEdgeNodeRedDemoNetwork

Préparez le Docker Compose dans le fichier

Copiez le contenu du fichier YAML suivant sur votre périphérique de passerelle SiteWise Edge.

services: influxdb: image: influxdb:latest container_name: influxdb ports: - "127.0.0.1:8086:8086" volumes: - influxdb-storage:/.influxdbv2 environment: - DOCKER_INFLUXDB_INIT_MODE=setup - DOCKER_INFLUXDB_INIT_USERNAME=admin - DOCKER_INFLUXDB_INIT_PASSWORD=${INFLUXDB_PASSWORD} - DOCKER_INFLUXDB_INIT_ORG=iot-sitewise-edge - DOCKER_INFLUXDB_INIT_BUCKET=WindFarmData - DOCKER_INFLUXDB_INIT_RETENTION=0 - DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=${INFLUXDB_TOKEN} networks: - SiteWiseEdgeNodeRedDemoNetwork restart: unless-stopped grafana: image: grafana/grafana:latest container_name: grafana ports: - "127.0.0.1:3000:3000" volumes: - grafana-storage:/var/lib/grafana - ./grafana/provisioning:/etc/grafana/provisioning environment: - GF_SECURITY_ADMIN_USER=admin - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD} - GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource - GF_PATHS_PROVISIONING=/etc/grafana/provisioning - GF_PATHS_CONFIG=/etc/grafana/grafana.ini - GF_LOG_LEVEL=info configs: - source: grafana_datasource target: /etc/grafana/provisioning/datasources/influxdb.yaml - source: grafana_preload_dashboard_config target: /etc/grafana/provisioning/dashboards/dashboard.yml - source: grafana_preload_dashboard target: /etc/grafana/provisioning/dashboards/demo_dashboard.json depends_on: - influxdb networks: - SiteWiseEdgeNodeRedDemoNetwork restart: unless-stopped nodered: build: context: . dockerfile_inline: | FROM nodered/node-red:latest RUN npm install node-red-contrib-influxdb container_name: nodered ports: - "127.0.0.1:1880:1880" volumes: - node_red_data:/data environment: - NODE_RED_ENABLE_SAFE_MODE=false - NODE_RED_ENABLE_PALETTE_EDIT=true - NODE_RED_AUTO_INSTALL_MODULES=true configs: - source: nodered_flows target: /data/flows.json - source: nodered_settings target: /data/settings.js - source: nodered_flows_cred target: /data/flows_cred.json depends_on: - influxdb networks: - SiteWiseEdgeNodeRedDemoNetwork restart: unless-stopped volumes: influxdb-storage: grafana-storage: node_red_data: networks: SiteWiseEdgeNodeRedDemoNetwork: external: true configs: grafana_datasource: content: | apiVersion: 1 datasources: - name: windfarm-demo type: influxdb access: proxy url: http://influxdb:8086 jsonData: version: Flux organization: iot-sitewise-edge defaultBucket: WindFarmData tlsSkipVerify: true secureJsonData: token: ${INFLUXDB_TOKEN} editable: false grafana_preload_dashboard_config: content: | apiVersion: 1 providers: - name: "Dashboard provider" orgId: 1 type: file options: path: /etc/grafana/provisioning/dashboards grafana_preload_dashboard: content: | { "annotations": { "list": [ { "builtIn": 1, "datasource": { "type": "grafana", "uid": "-- Grafana --" }, "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "type": "dashboard" } ] }, "editable": true, "fiscalYearStartMonth": 0, "graphTooltip": 0, "id": 1, "links": [], "panels": [ { "datasource": { "type": "influxdb", "uid": "PEB0DCBF338B3CEB2" }, "fieldConfig": { "defaults": { "color": { "mode": "palette-classic" }, "custom": { "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 0, "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, "scaleDistribution": { "type": "linear" }, "showPoints": "auto", "spanNulls": false, "stacking": { "group": "A", "mode": "none" }, "thresholdsStyle": { "mode": "off" } }, "mappings": [], "thresholds": { "mode": "absolute", "steps": [ { "color": "green" }, { "color": "red", "value": 80 } ] } }, "overrides": [] }, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 }, "id": 1, "options": { "legend": { "calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true }, "tooltip": { "hideZeros": false, "mode": "single", "sort": "none" } }, "pluginVersion": "11.6.0", "targets": [ { "datasource": { "type": "influxdb", "uid": "PEB0DCBF338B3CEB2" }, "query": "from(bucket: \"WindFarmData\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"TurbineData\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> filter(fn: (r) => r[\"name\"] == \"/Renton/WindFarm/Turbine/WindSpeed\")\n |> filter(fn: (r) => r[\"quality\"] == \"GOOD\")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")", "refId": "A" } ], "title": "Wind Speed", "type": "timeseries" } ], "preload": false, "schemaVersion": 41, "tags": [], "templating": { "list": [] }, "time": { "from": "now-6h", "to": "now" }, "timepicker": {}, "timezone": "browser", "title": "Demo Dashboard", "uid": "eejtureqjo9a8c", "version": 2 } nodered_flows: content: | [ { "id": "95fce448fdd43b47", "type": "tab", "label": "Demo Flow", "disabled": false, "info": "" }, { "id": "5f63740b66af3386", "type": "mqtt out", "z": "95fce448fdd43b47", "name": "Publish to MQTT broker", "topic": "/Renton/WindFarm/Turbine/WindSpeed", "qos": "1", "retain": "", "respTopic": "", "contentType": "", "userProps": "", "correl": "", "expiry": "", "broker": "5744207557fa19be", "x": 830, "y": 200, "wires": [] }, { "id": "8f2eb590d596679b", "type": "function", "z": "95fce448fdd43b47", "name": "Translate to SiteWise payload", "func": "let input = msg.payload;\nlet output = {};\n\noutput[\"propertyAlias\"] = input.name;\n\nlet propertyVal = {}\n\nlet timeInSeconds = Math.floor(input.timestamp / 1000);\nlet offsetInNanos = (input.timestamp % 1000) * 1000000;\n\npropertyVal[\"timestamp\"] = {\n \"timeInSeconds\": timeInSeconds,\n \"offsetInNanos\": offsetInNanos,\n};\n\npropertyVal[\"quality\"] = input.quality\n\nlet typeNameConverter = {\n \"number\": (x) => Number.isInteger(x) ? \"integerValue\" : \"doubleValue\",\n \"boolean\": (x) => \"booleanValue\",\n \"string\": (x) => \"stringValue\", \n}\nlet typeName = typeNameConverter[typeof input.value](input.value)\npropertyVal[\"value\"] = {}\npropertyVal[\"value\"][typeName] = input.value;\n\noutput[\"propertyValues\"] = [propertyVal]\n\nreturn {\n payload: JSON.stringify(output)\n};", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 530, "y": 200, "wires": [ [ "5f63740b66af3386" ] ] }, { "id": "4b78cbdea5e3258c", "type": "inject", "z": "95fce448fdd43b47", "name": "Turbine Simulator", "props": [ { "p": "payload.timestamp", "v": "", "vt": "date" }, { "p": "payload.quality", "v": "GOOD", "vt": "str" }, { "p": "payload.value", "v": "$$random()", "vt": "jsonata" }, { "p": "payload.name", "v": "/Renton/WindFarm/Turbine/WindSpeed", "vt": "str" } ], "repeat": "1", "crontab": "", "once": false, "onceDelay": "", "topic": "", "x": 270, "y": 200, "wires": [ [ "8f2eb590d596679b" ] ] }, { "id": "b658bf337ea2e316", "type": "influxdb out", "z": "95fce448fdd43b47", "influxdb": "2f1c38495035d2e4", "name": "Store data in InfluxDB", "measurement": "TurbineData", "precision": "", "retentionPolicy": "", "database": "", "retentionPolicyV18Flux": "", "org": "iot-sitewise-edge", "bucket": "WindFarmData", "x": 840, "y": 340, "wires": [] }, { "id": "9432d39af35b202f", "type": "function", "z": "95fce448fdd43b47", "name": "Translate to InfluxDB payload", "func": "let data = msg.payload;\n\nlet timeInSeconds = data.propertyValues[0].timestamp.timeInSeconds;\nlet offsetInNanos = data.propertyValues[0].timestamp.offsetInNanos;\nlet timestampInMilliseconds = (timeInSeconds * 1000) + (offsetInNanos / 1000000);\n\nmsg.payload = [\n {\n \"timestamp(milliseconds_since_epoch)\": timestampInMilliseconds,\n \"value\": data.propertyValues[0].value.doubleValue\n },\n {\n \"name\": data.propertyAlias,\n \"quality\": data.propertyValues[0].quality\n }\n]\n\nreturn msg", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 560, "y": 340, "wires": [ [ "b658bf337ea2e316" ] ] }, { "id": "b689403d2c80816b", "type": "mqtt in", "z": "95fce448fdd43b47", "name": "Subscribe to MQTT broker", "topic": "/Renton/WindFarm/Turbine/WindSpeed", "qos": "1", "datatype": "auto-detect", "broker": "5744207557fa19be", "nl": false, "rap": true, "rh": 0, "inputs": 0, "x": 290, "y": 340, "wires": [ [ "9432d39af35b202f" ] ] }, { "id": "4f59bed8e829fc35", "type": "comment", "z": "95fce448fdd43b47", "name": "Data Publish Flow", "info": "dfgh", "x": 270, "y": 160, "wires": [] }, { "id": "b218c7fc58c8b6e7", "type": "comment", "z": "95fce448fdd43b47", "name": "Data Retention flow", "info": "", "x": 270, "y": 300, "wires": [] }, { "id": "5744207557fa19be", "type": "mqtt-broker", "name": "emqx", "broker": "emqx", "port": "1883", "clientid": "", "autoConnect": true, "usetls": false, "protocolVersion": "5", "keepalive": 15, "cleansession": true, "autoUnsubscribe": true, "birthTopic": "", "birthQos": "0", "birthPayload": "", "birthMsg": {}, "closeTopic": "", "closePayload": "", "closeMsg": {}, "willTopic": "", "willQos": "0", "willPayload": "", "willMsg": {}, "userProps": "", "sessionExpiry": "" }, { "id": "2f1c38495035d2e4", "type": "influxdb", "hostname": "influxdb", "port": 8086, "protocol": "http", "database": "", "name": "InfluxDB", "usetls": false, "tls": "", "influxdbVersion": "2.0", "url": "http://influxdb:8086", "timeout": "", "rejectUnauthorized": false } ] nodered_flows_cred: content: | { "2f1c38495035d2e4": { "token": "${INFLUXDB_TOKEN}" } } nodered_settings: content: | module.exports = { flowFile: 'flows.json', credentialSecret: false, adminAuth: null, editorTheme: { projects: { enabled: false } } }

Mettre à jour le déploiement SiteWise Edge

  1. Accédez à la AWS IoT console

  2. Choisissez les appareils Greengrass dans le menu de navigation de gauche, dans la section Gérer, puis les appareils principaux.

  3. Sélectionnez l'appareil principal connecté à votre passerelle SiteWise Edge.

  4. Choisissez l'onglet Déploiements, puis sélectionnez la valeur ID de déploiement.

  5. Choisissez Actions, puis sélectionnez Réviser.

  6. Lisez le message qui s'affiche, puis choisissez Réviser le déploiement.

  7. À l'étape 2 - Sélectionnez les composants, sélectionnez les composants suivants, puis choisissez Suivant.

    • aws.greengrass.clientdevices.mqtt.EMQX

    • aws.iot.SiteWiseEdgePublisher

  8. À l'étape 3 - Configuration des composants, sélectionnez la valeur du aws.greengrass.clientdevices.mqtt.EMQX composant et ajoutez la configuration réseau suivante :

    { "emqxConfig": { "authorization": { "no_match": "allow" }, "listeners": { "tcp": { "default": { "enabled": true, "enable_authn": false } } } }, "authMode": "bypass", "dockerOptions": "-p 127.0.0.1:1883:1883 --network=SiteWiseEdgeNodeRedDemoNetwork", "requiresPrivilege": "true" }
  9. Choisissez Suivant.

  10. À l'étape 4 - Configurer les paramètres avancés, choisissez Suivant.

  11. Choisissez Deploy

Lancer les services

  1. Démarrez les services à l'aide du fichier Docker Compose. Exécutez la commande suivante dans le répertoire contenant le compose.yaml fichier.

    docker compose up -d
  2. Créez un tunnel SSH pour accéder aux services :

    ssh -i path_to_your_ssh_key -L 1880:127.0.0.1:1880 -L 3000:127.0.0.1:3000 -L 8086:127.0.0.1:8086 username@gateway_ip_address

Ce déploiement crée les services suivants dans SiteWiseEdgeNodeRedDemoNetwork network :

InfluxDB v2 (port 8086)

Comprend une organisation préconfigurée (iot-sitewise-edge), un bucket InfluxDB et des informations d'identification d'administrateur WindFarmData

Node-RED (port 1880)

Inclut des nœuds InfluxDB et des flux préconfigurés pour l'intégration AWS IoT SiteWise

Grafana (port 3000)

Comprend un utilisateur administrateur, une source de données InfluxDB et un tableau de bord de surveillance

Accédez aux services

Après le déploiement, accédez aux services à l'aide des URL et informations d'identification suivantes :

Note

Vous pouvez accéder à chaque service depuis votre hôte ou la machine passerelle.

Informations sur l'accès au service
Service URL Informations d’identification
Node-RED http://127.0.0.1:1880 Aucune information d'identification requise
InfluxDB http://127.0.0.1: 8086

Nom d'utilisateur : admin

Mot de passe : $INFLUXDB_PASSWORD

Grafana http://127.0.0.1:3000

Nom d'utilisateur : admin

Mot de passe : $GRAFANA_PASSWORD

Vérification du déploiement

Pour garantir la réussite de votre déploiement, effectuez les vérifications suivantes :

  1. Pour Node-RED, vérifiez la présence de deux flux préchargés :

    • Flux de publication des données

    • Flux de conservation des données

  2. Pour AWS IoT SiteWise, dans la AWS IoT SiteWise console, confirmez la présence d'un flux de données avec l'alias/Renton/WindFarm/Turbine/WindSpeed.

  3. Pour InfluxDB, utilisez l'explorateur de données pour vérifier le stockage des données dans la TurbineData mesure au sein du WindFarmData bucket.

  4. Pour Grafana, consultez le tableau de bord pour confirmer l'affichage des données chronologiques générées à partir de Node-RED.