|
| 1 | +/* |
| 2 | + * Copyright (c) University of Sheffield AMRC 2026. |
| 3 | + */ |
| 4 | + |
| 5 | +/* |
| 6 | + * ACS Edge OPC UA Server - Entry Point |
| 7 | + * |
| 8 | + * Reads configuration from a mounted ConfigMap file and credentials |
| 9 | + * from environment variables, initialises the data store, MQTT client |
| 10 | + * (via ServiceClient), and OPC UA server. |
| 11 | + */ |
| 12 | + |
| 13 | +import fs from "node:fs"; |
| 14 | + |
| 15 | +import { ServiceClient } from "@amrc-factoryplus/service-client"; |
| 16 | + |
| 17 | +import { DataStore } from "../lib/data-store.js"; |
| 18 | +import { MqttClient } from "../lib/mqtt-client.js"; |
| 19 | +import { Server } from "../lib/server.js"; |
| 20 | + |
| 21 | +/* Read configuration from files. */ |
| 22 | +const configFile = process.env.CONFIG_FILE ?? "/config/config.json"; |
| 23 | +const dataDir = process.env.DATA_DIR ?? "/data"; |
| 24 | + |
| 25 | +const config = JSON.parse(fs.readFileSync(configFile, "utf-8")); |
| 26 | + |
| 27 | +/* Read OPC UA credentials from environment variables. */ |
| 28 | +const opcuaUsername = process.env.OPCUA_USERNAME; |
| 29 | +const opcuaPassword = process.env.OPCUA_PASSWORD; |
| 30 | + |
| 31 | +if (!opcuaUsername || !opcuaPassword) { |
| 32 | + console.error("OPCUA_USERNAME and OPCUA_PASSWORD must be set"); |
| 33 | + process.exit(1); |
| 34 | +} |
| 35 | + |
| 36 | +/* Build ServiceClient - reads SERVICE_USERNAME, SERVICE_PASSWORD, |
| 37 | + * DIRECTORY_URL, VERBOSE from process.env. */ |
| 38 | +const fplus = await new ServiceClient({ env: process.env }).init(); |
| 39 | + |
| 40 | +/* Initialise components. */ |
| 41 | +const dataStore = new DataStore({ dataDir }); |
| 42 | +dataStore.start(); |
| 43 | + |
| 44 | +const mqttClient = new MqttClient({ |
| 45 | + fplus, |
| 46 | + topics: config.topics, |
| 47 | + dataStore, |
| 48 | +}); |
| 49 | + |
| 50 | +const server = new Server({ |
| 51 | + port: config.opcua.port, |
| 52 | + dataStore, |
| 53 | + username: opcuaUsername, |
| 54 | + password: opcuaPassword, |
| 55 | + allowAnonymous: config.opcua.allowAnonymous ?? false, |
| 56 | +}); |
| 57 | + |
| 58 | +/* Start everything. */ |
| 59 | +await mqttClient.start(); |
| 60 | +await server.start(); |
| 61 | + |
| 62 | +console.log(`OPC UA server ready. Subscribed to ${config.topics.length} MQTT topic pattern(s).`); |
| 63 | + |
| 64 | +/* Graceful shutdown. */ |
| 65 | +const shutdown = async (signal) => { |
| 66 | + console.log(`Received ${signal}, shutting down...`); |
| 67 | + await server.stop(); |
| 68 | + await mqttClient.stop(); |
| 69 | + dataStore.stop(); |
| 70 | + process.exit(0); |
| 71 | +}; |
| 72 | + |
| 73 | +process.on("SIGINT", () => shutdown("SIGINT")); |
| 74 | +process.on("SIGTERM", () => shutdown("SIGTERM")); |
0 commit comments