# Proxus documentation # Get started > What Proxus is, who uses it, and the shortest path from an installed hub to live machine data. Source: https://proxus.io/docs/get-started Proxus is an industrial data platform. It reads the machines of a plant, gives every value a place in one shared structure, keeps its history, acts on it, and passes it on to the people and systems that use it. One installation does the work that usually takes a collection of separate products: connectivity, edge processing, a historian, alarms, dashboards and reports, integration and AI. You run it yourself: on one server, on several sites, or next to the machines. ## What Proxus does ### Connect - **Reads machines.** The edge gateway speaks the protocols of PLCs, CNC controls, robots, meters and sensors: OPC UA, Modbus, SNMP, MTConnect and the native protocols of Siemens, Rockwell, Mitsubishi, Omron, Beckhoff, Fanuc, Haas, Heidenhain and many more vendors. See [Protocols](https://proxus.io/docs/reference/protocols). Devices that send their own values publish them to the gateway's [MQTT broker](https://proxus.io/docs/develop/mqtt). - **Sets machines up quickly.** A wizard tests the connection and browses the device's own tag list; devices can also be imported from a spreadsheet or [from Kepware](https://proxus.io/docs/connect/devices/kepware-import). - **Works next to the machine.** The [edge gateway](https://proxus.io/docs/connect/edge-gateways/install-a-gateway) reads, processes and buffers data on site, and keeps it while the link to the hub is down. ### Organize - **Gives every value a place.** Each device sits in the plant's structure (enterprise, site, area, process cell), and its values are published under that place in the [Unified Namespace](https://proxus.io/docs/concepts/unified-namespace). - **Shows what depends on what.** [Health Checks](https://proxus.io/docs/organize/health-checks) find broken links and wasted data, the [operational graph](https://proxus.io/docs/organize/operational-graph) shows what a change affects, and [application templates](https://proxus.io/docs/organize/app-templates) carry a working setup to another hub. ### Process and automate - **Pipelines without code.** [Pipelines](https://proxus.io/docs/automate/pipelines) clean, convert, window, calculate and route values from ready-made [nodes](https://proxus.io/docs/reference/pipeline-nodes), rehearsed on stored data before they go live. - **Rules and alarms.** [Rules](https://proxus.io/docs/automate/rules) watch values, device status, logs and gateway metrics, raise alarms and run actions. Anomaly detection catches values that leave their usual pattern. - **Your own code.** [Functions](https://proxus.io/docs/automate/functions) are C# code that runs on the edge gateways. ### Store and analyze - **Keeps the history.** Every value of a device that delivers to the Proxus historian (new devices do by default) is stored with its time, with no separate archive product to license. Trend it, compare it with earlier periods and export it in the [Trend Workspace](https://proxus.io/docs/monitor/trend-workspace). - **Dashboards and reports.** [Dashboards](https://proxus.io/docs/analyze/dashboards) and [reports](https://proxus.io/docs/analyze/reports) draw on the history and the plant model, and [scheduled delivery](https://proxus.io/docs/analyze/scheduled-delivery) e-mails them. ### Monitor and respond - **Watches the plant live.** The [Operations Center](https://proxus.io/docs/monitor/operations-center), the [Topology](https://proxus.io/docs/monitor/topology) and the [device page](https://proxus.io/docs/connect/devices/device-page) show what needs attention, and [alerts](https://proxus.io/docs/monitor/alerts) are taken, followed and closed with a note. - **Tells people.** [Notification channels](https://proxus.io/docs/reference/notification-channels) send messages by e-mail, SMS, WhatsApp, Microsoft Teams, Slack, Telegram and other services. ### Share - **Sends data on.** [Outbound targets](https://proxus.io/docs/reference/outbound-targets) deliver values to SQL databases, time-series databases, message brokers such as Kafka and MQTT, cloud services and REST APIs. - **Opens it to software.** A [REST API](https://proxus.io/docs/develop/rest-api), a [telemetry API](https://proxus.io/docs/develop/telemetry-api), [MQTT topics](https://proxus.io/docs/develop/mqtt) and an [MCP server](https://proxus.io/docs/develop/mcp) for AI agents. ### AI - **Copilot.** [Copilot](https://proxus.io/docs/monitor/copilot) answers questions about the plant in plain language, finds why a device stopped, summarizes a shift, and prepares changes and actions that run only after you approve them. It sees only what the user may see. ### Secure and run - **Permissions and records.** [Roles](https://proxus.io/docs/administer/users-and-roles) and [UNS permissions](https://proxus.io/docs/administer/uns-permissions) limit who sees and changes what, down to one site or line, and the [audit trail](https://proxus.io/docs/administer/audit-trail) records who changed what and when. - **Runs where you need it.** [Docker](https://proxus.io/docs/operate/docker) on one server, or [Kubernetes](https://proxus.io/docs/operate/kubernetes) with high availability. ## Who it is for | Reader | Starts with | | --- | --- | | Operator | [A guided tour of the hub](https://proxus.io/docs/get-started/tour), then [Monitor](https://proxus.io/docs/monitor) | | Engineer or integrator | [Connect your first machine](https://proxus.io/docs/get-started/first-machine), then [Connect](https://proxus.io/docs/connect) | | Administrator or IT | [Install Proxus with Docker](https://proxus.io/docs/get-started/install) and the [system requirements](https://proxus.io/docs/get-started/system-requirements) | | Developer | [How Proxus is built](https://proxus.io/docs/concepts/architecture), then [Develop](https://proxus.io/docs/develop) | > **Tip:** Take a free trial key yourself in the [Proxus portal](https://portal.proxus.io), or see Proxus on your data in a 30-minute session. [Get a free 30-day trial key](/try#licence) · [Book a demo](/demo) ## Start here ## Learn how it fits together The [Concepts](https://proxus.io/docs/concepts) section explains the building blocks: the hub and its edge gateways, how a value travels from a machine to a report, devices and tags, the Unified Namespace, and when to use a pipeline, a rule or a function. --- # System requirements > The software, network ports and resources the Proxus hub and its edge gateways need, as set by the Docker Compose stack. Source: https://proxus.io/docs/get-started/system-requirements This page lists what the Proxus hub and its edge gateways need to run. It follows the Docker Compose stack that [Install Proxus with Docker](https://proxus.io/docs/get-started/install) uses. Proxus does not set a minimum machine size: the memory, processor and disk a hub needs depend on how many values per second it receives and how long you keep them. [Size the machines](#size-the-machines) shows how to work that out for your site. ## Software | Component | Needs | | --- | --- | | Hub host | Docker Engine with the Docker Compose plugin (`docker compose`). | | Edge gateway host | Docker Engine for the Docker install, where a remote gateway runs as a container next to a small message server container of its own. [Install an edge gateway](https://proxus.io/docs/connect/edge-gateways/install-a-gateway) describes the options. | | Users | A current web browser. Nothing is installed on the user's computer. | The compose file uses these images: | Service | Image | | --- | --- | | `proxus-ui` (the hub) | `proxusplatform/proxus-ui` | | `proxus-server` (the SYSTEM gateway) | `proxusplatform/proxus-server` | | `hub-server` (message server) | `nats` (Alpine variant) | | `postgresql` (configuration database) | `postgres:16` | | `clickhouse` (historian) | `bitnamilegacy/clickhouse` | ## Network ports The ports the compose file publishes on the hub host: | Port | Service | Used for | | --- | --- | --- | | `8443` | `proxus-ui` | The hub's web interface over HTTPS. Users need it. | | `8080` | `proxus-ui` | The hub's web interface over HTTP, for local access. | | `8083` | `proxus-server` | The SYSTEM gateway's HTTP endpoint (health check, values sent over HTTP). | | `1883` | `proxus-server` | The SYSTEM gateway's MQTT broker: devices that publish over MQTT, and applications that subscribe to the Unified Namespace. | | `8883` | `proxus-server` | The same MQTT broker over TLS. | | `7422` | `hub-server` | Remote edge gateways connect here, over TLS. Open it from every gateway's network to the hub. | | `4222` | `hub-server` | Message server clients inside the stack, over TLS. | | `8222` | `hub-server` | The message server's monitoring page. | | `5442` | `postgresql` | The configuration database. | | `8123`, `9000`, `9004`, `9005` | `clickhouse` | The historian over HTTP, its native protocol, and its MySQL and PostgreSQL protocols. | Only `8443` is needed by users, `7422` and `8443` by remote gateways, and `1883` by MQTT devices and subscribers. Remote gateways also listen on `8883` for MQTT over TLS. The others can stay closed to the network; [Security hardening](https://proxus.io/docs/operate/security) explains how. [Network ports](https://proxus.io/docs/reference/ports) lists every port, including those of remote gateways. ## Resources - **Memory.** The compose file limits the ClickHouse container to 8 GB of memory and gives PostgreSQL 1 GB of shared memory. The host needs room for both, plus the hub, the gateway and the message server. On a smaller host, lower the ClickHouse limit (see [Docker](https://proxus.io/docs/operate/docker#adjust-the-stack-for-your-site)). - **Disk for the images.** The first download of the images is about 2 to 3 GB. - **Disk for the historian.** The historian keeps every value until you set a retention period, so its volume grows with your data rate. [Configuration](https://proxus.io/docs/administer/configuration) explains the retention settings. - **Disk on remote gateways.** A gateway keeps values it cannot deliver to the hub, for 48 hours by default (**Buffer Retention (hours)** on the gateway, from 1 to 720). It needs disk for that many hours at its data rate. See [How data flows](https://proxus.io/docs/concepts/data-flow). - **No internet access.** The hub and the gateways run without it. See [Install without internet access](https://proxus.io/docs/operate/offline-install). ## Size the machines The size of a Proxus installation follows from one number: how many values per second (dp/s) your devices produce. Work it out, check it against the license, then measure the disk on a running system. ### 1. Count the values per second For each device, divide the number of tags by how often they are read. 600 tags read every second give at most 600 dp/s; 600 tags read every 10 seconds give at most 60 dp/s. Add up the devices of each gateway, and of the whole site. A day has 86,400 seconds, so 1,000 dp/s is up to 86.4 million values a day. ### 2. Check the rate against the license Each gateway may pass on a sustained number of values per second, set by its capacity tier, with a short burst reserve for peaks. Values above the limit are dropped. If a gateway's devices add up to more than its tier allows, spread the devices over more gateways or choose a larger tier. [License](https://proxus.io/docs/administer/license) explains the limits; [Pricing](/pricing) lists the tiers and their rates. ### 3. Measure the disk, then multiply How much disk a value takes depends on the data: the historian compresses values, and values that change little compress well. Measure it on your own data instead of guessing. 1. Run the hub with the real devices, or with a representative part of them, for a day. 2. Open **Platform > Database Health**. **Database Summary** shows the size of the stored values on disk. 3. Multiply the growth of one day by the number of days you keep values, and leave free space on top. When the disk is full, new values can no longer be stored. To stop the volume growing without limit, set `[ClickHouse] ClickHouseTTLExpression`, for example to one year. See [Configuration keys](https://proxus.io/docs/reference/configuration#clickhouse). ### 4. Watch it after go-live - **Platform > License Info** shows each gateway's **Observed dp/s** against its licensed rate. See [Monitoring](https://proxus.io/docs/operate/monitoring). - **Connect > Edge Gateways** shows the **CPU** and **Memory** each gateway process uses on its machine. - **Platform > Database Health** shows the free space on the historian's disk. > **Tip:** Bring your device and tag counts to a 30-minute technical session and size the hub and gateways with a Proxus engineer. [Book a demo](/demo) ## Time The hub and the gateway take their time zone from the `TZ` setting in the compose file. Values are stored in UTC; the hub shows them in the user's time zone. ## What's next - [Install Proxus with Docker](https://proxus.io/docs/get-started/install): run the hub on one machine. - [Network ports](https://proxus.io/docs/reference/ports): every port, including those of remote gateways. - [Security hardening](https://proxus.io/docs/operate/security): close the ports you do not use and change the default passwords. --- # Install Proxus with Docker > Run the Proxus hub, its databases, its message server and the built-in edge gateway with Docker Compose on one machine, then sign in. Source: https://proxus.io/docs/get-started/install At the end of this guide, Proxus runs on one machine with Docker Compose and you are signed in to the hub. This setup suits a trial, a demo or a small site. For production, read [Run Proxus with Docker](https://proxus.io/docs/operate/docker) as well. ## Before you start You need: - A machine with **Docker Engine** and the **Docker Compose** plugin (the `docker compose` command). See the [system requirements](https://proxus.io/docs/get-started/system-requirements). - Internet access to `proxus.io` for the installer. If you install from a compose file you received with your Proxus delivery instead, have that `docker-compose.yml` ready. - Access to Docker Hub, where the Proxus images (`proxusplatform/proxus-ui` and `proxusplatform/proxus-server`) and the database and message server images are published. On a network without internet access, follow [Install without internet access](https://proxus.io/docs/operate/offline-install) instead. - These ports free on the machine: `8080`, `8443`, `8083`, `1883`, `8883`, `4222`, `8222`, `7422`, `5442`, `8123`, `9000`, `9004` and `9005`. [Network ports](https://proxus.io/docs/reference/ports) says what each one is for. - A license key from Proxus or your distributor. You can also start without one and send the **License ID** the hub shows on its first start. > **Tip:** Take a free trial key yourself in the [Proxus portal](https://portal.proxus.io), or see Proxus on your data in a 30-minute session. [Get a free 30-day trial key](/try#licence) · [Book a demo](/demo) ## What the compose file starts | Service | What it is | | --- | --- | | `proxus-ui` | The **hub**: the web interface on port `8443` (HTTPS) and `8080` (HTTP), the hub's services, and the place where users, devices and settings are managed. | | `proxus-server` | The **SYSTEM** edge gateway, which runs next to the hub. It reads devices on the hub's network, and its built-in MQTT broker listens on port `1883` and, over TLS, on `8883`. | | `hub-server` | The NATS message server that carries data and configuration between the hub and its gateways. All its connections use TLS. Remote gateways connect to it on port `7422`. | | `postgresql` | The PostgreSQL database that keeps the configuration: devices, profiles, rules, users. It listens on port `5442`. | | `clickhouse` | The ClickHouse database that is the Proxus historian: every value and the system logs. | Each service keeps its data on a named Docker volume (`proxus-db-volume`, `clickhouse_data`, `nats`, `config`, `proxus_modules`), so the data survives a restart or an image update. ## Install with the installer The installer is the quickest way to start. It checks that Docker and Docker Compose are ready, asks for the display language format and the time zone, writes `docker-compose.yml` into a new `proxus-platform` folder and, if you agree, starts the stack. 1. Open a terminal on the machine and run the installer for its operating system: ```bash curl -fsSL https://proxus.io/install.sh | bash ``` ```powershell irm https://proxus.io/install.ps1 | iex ``` If your Docker setup needs it, run the command with `sudo` on Linux, or open PowerShell as administrator on Windows. 2. Answer the installer's questions: - **Culture** sets how numbers and dates are shown, for example `tr-TR` or `en-US`. The installer suggests the machine's own setting. - **Timezone** sets the time in the containers and in the log files, for example `Europe/Istanbul`. The installer then shows the machine address it found ("Address edge gateways use"). The hub offers it when you install an edge gateway. See [Keep the hub's address stable](#keep-the-hubs-address-stable). - **Start the platform now?** Answer `Y` to download the images and start the services at once. The first download is about 2 to 3 GB. Answer `n` to start later with `docker compose up -d` in the `proxus-platform` folder. 3. Check that every service is running and healthy: ```bash cd proxus-platform docker compose ps ``` The health checks can take one or two minutes to turn green after the first start. If a `docker-compose.yml` already exists in `proxus-platform`, the installer keeps a copy of it before it writes the new one. If Docker is missing, the Docker service is not running or Docker Compose v2 is not installed, the installer stops with a clear message and writes nothing. Then continue with [Sign in for the first time](#sign-in-for-the-first-time). ## Install from a compose file Use this way when your Proxus delivery includes a prepared compose file, or when the machine cannot reach `proxus.io`. If it cannot reach Docker Hub either, load the images first as in [Install without internet access](https://proxus.io/docs/operate/offline-install). 1. Create a folder for Proxus, for example `/opt/proxus`, and copy `docker-compose.yml` into it. 2. Set the time zone. In the compose file, the `x-dotnet-env` block sets `TZ` for the hub and the gateway. Change it to the plant's zone, for example: ```yaml x-dotnet-env: &dotnet-env TZ: Europe/Paris ``` The hub and the gateway write the times in their log files in this zone. 3. In the folder, start the stack: ```bash docker compose up -d ``` Docker downloads the images the first time, then starts the five services. 4. Wait until every service is running and healthy: ```bash docker compose ps ``` On the first start the hub creates its database tables, the message server's security settings and the platform's certificate authority (the **Proxus Platform CA**), so it takes longer than later starts. Until the hub has done this, the `hub-server` log repeats `Waiting for Proxus UI to create the NATS trust`. That is expected. 5. Check that the hub answers. This prints `Healthy` when it is ready: ```bash curl http://localhost:8080/healthz ``` > **Warning:** The compose file publishes the database and message server ports on the host and uses the default database passwords. That is fine on a test machine. Before you connect a plant network, follow [Security hardening](https://proxus.io/docs/operate/security). ## Sign in for the first time *Screenshot: The Proxus sign-in form with the user name and password fields and the language list* 1. Open `https://:8443` in a browser, where `` is the machine's name or IP address (`https://localhost:8443` on the machine itself). The hub's certificate is issued by the Proxus Platform CA, which your browser does not know yet, so it shows a warning the first time. Continue to the page, or open `http://:8080` instead. To remove the warning, install the platform CA on your computer (see [Certificates](https://proxus.io/docs/administer/certificates#make-browsers-and-devices-trust-the-platform)). 2. If the form is not in your language, pick it from the list at the top right of the form. 3. Enter the user name `Admin` and leave **Password** empty. Select **Log In**. 4. A new hub has no license yet, so the **License Activation** window opens. Paste the key you received and activate it. The key works only on this installation; the window shows the **License ID** to send when you order one. If you close the window without activating, you are signed out. [License](https://proxus.io/docs/administer/license) explains licenses in detail. 5. You now see the **Operations Center**. ## Secure the first accounts The first start creates one administrator account, `Admin`, with an empty password. Before anyone else can reach the hub, open the user menu at the top right, select **My Details**, then **Change My Password**, and set a strong password. For API access, add a user of its own on **Security > Users**. [Users and roles](https://proxus.io/docs/administer/users-and-roles) explains how to add accounts for your team. ## Keep the hub's address stable Each edge gateway is installed with the hub address you choose in its install wizard and connects to that address only. If the hub machine gets a new IP address later, for example from DHCP, the edge gateways lose their connection and each one must be installed again. - In production, give the hub a fixed address: a DHCP reservation or a static IP, or better, a DNS name such as `proxus.plant.local`. With a DNS name, an IP change does not affect any edge gateway. - The install wizard first offers the address you opened the hub on, then the address the installer found. Open the hub on the address the edge machines use, so that the right one comes first. - To change the address the hub offers, edit the `Service__PublicAddress` line of the `proxus-ui` service in `proxus-platform/docker-compose.yml` (several addresses or DNS names separated by commas), then run `docker compose up -d`. Running the installer again also detects the address again. ## Keep the certificate key The hub keeps the private keys of its certificates encrypted. The key for them is in the `config` volume (`keys/STORE/certificate-store.key`). Include the `config` volume in every backup: without this key, the certificates cannot be read after a restore. See [Backup and restore](https://proxus.io/docs/operate/backup-and-restore). ## What's next - [Connect your first machine](https://proxus.io/docs/get-started/first-machine) with the built-in simulator. - [A tour of the hub](https://proxus.io/docs/get-started/tour) shows what each screen is for. - [Run Proxus with Docker](https://proxus.io/docs/operate/docker) covers production settings, updates and backups. - [Configuration](https://proxus.io/docs/administer/configuration) explains the configuration file. Docker keeps it on the `config` volume, where the hub writes it with its defaults on the first start. --- # Connect your first machine > A tutorial. Add a simulated mixer to an empty hub, watch its first values arrive, open its device page and draw a trend. No hardware needed. Source: https://proxus.io/docs/get-started/first-machine In this tutorial you connect a dough mixer to Proxus, watch its values arrive and draw them as a trend. The mixer is simulated: the **Simulator** protocol makes values on the gateway itself, so you need no PLC, no network address and no cabling. Everything you do here is what you later do with a real machine. You will: 1. Add the mixer with the device setup wizard: three tags for temperature, speed and level. 2. Check that the gateway is reading it. 3. Look at its device page. 4. Draw its temperature and speed in the Trend Workspace. ## Before you start - A running hub you can sign in to. If you have none yet, [install Proxus with Docker](https://proxus.io/docs/get-started/install). - A user who may create devices. The `Admin` account can. The hub's own gateway, **SYSTEM**, runs the simulator, so you do not need to install a gateway. ## Step 1: Open the device setup wizard 1. In the menu, go to **Connect > Devices**. 2. Select **New** in the toolbar. The wizard opens in a new tab. If it asks whether to **Carry on** with an earlier draft or **Start over**, select **Start over**. ## Step 2: Choose the gateway and the protocol *Screenshot: The first wizard step with the SYSTEM gateway selected, simulator typed in the protocol search and the Simulator card selected* 1. Under **Gateway**, select **SYSTEM** (1). It shows **Connected** when it is online. Your hub may list other gateways too. 2. In the protocol search box (2), type `simulator`. 3. Select the **Simulator** card (3). 4. Leave **Start from** at **A new profile**. 5. Select **Next: Connection**. ## Step 3: Test the connection *Screenshot: The connection step for the simulator with Read every left at Profile default and a passed connection test* A simulator has no address, so this step only asks how often to read. 1. Leave **Read every** (1) at **Profile default**. 2. Select **Test the connection** (2). The test checks that the gateway is ready to make values. 3. The result (3) shows **Connected** and the line "Simulator ready on SYSTEM". Select **Next: Tags**. ## Step 4: Add three tags A **tag** is one value you read from a machine. For a simulated tag, the **Address** is the range the value stays in, written as `[minimum,maximum]`, and the **Pattern** says how the value moves inside that range. *Screenshot: The Table tab with three simulated tags: Temperature, Speed and Level, each with a range address, a pattern and a test-read value* 1. The **Table** tab shows one empty row. Fill it in: | Name | Address | Type | Unit | Pattern | | --- | --- | --- | --- | --- | | `Temperature` | `[20,80]` | **Float** | `°C` | **Sine wave** | The address (1) keeps the temperature between 20 and 80 °C; the pattern (2) makes it rise and fall smoothly. 2. Select **Add a tag** (3) and fill in the second row. Do it once more for the third: | Name | Address | Type | Unit | Pattern | | --- | --- | --- | --- | --- | | `Speed` | `[0,1500]` | **Float** | `rpm` | **Random walk** | | `Level` | `[10,90]` | **Float** | `%` | **Triangle wave** | 3. Select **Read all once** (4). The gateway reads each tag one time and shows a value in the **Test read** column. The button now says **Read again**. 4. In **Profile name** (5), type `Mixer simulator`. The connection and the tags are saved as a device profile under this name, so a second mixer can reuse them. Select **Next: Place and type**. ## Step 5: Name and place the mixer *Screenshot: The place and type step with the device name DOCS_TUTORIAL_MIXER_01, the place Meridian, Lyon Foods Plant, Processing, Dough, and Mixer selected as the device type* 1. In **Device name** (1), type a unique name. This tutorial uses `DOCS_TUTORIAL_MIXER_01`; you can name it anything, for example after your own site, line and machine. 2. Fill in the place (2). Select each field and type a value, or pick one that already exists: - **Enterprise**: `Meridian` - **Site**: `Lyon Foods Plant` - **Area**: `Processing` - **Process cell**: `Dough` Leave **Equipment module** empty. The line under the fields shows the path the device will have in the Unified Namespace. 3. Under **Device type**, select **Mixer** (3). Further down, **Where does the data go?** shows the historian ticked: the values of every new device are stored. Leave the other targets unticked. Then select **Save and verify**. ## Step 6: Watch the first values *Screenshot: The verify step with the stages Saved, Sent to SYSTEM, Device connected and First values complete, and a value for each of the three tags* The wizard saves the device and follows it live: 1. The stages (1) complete in order: **Saved**, **Sent to SYSTEM**, **Device connected** and **First values** with **3 / 3**. 2. Each tag (2) shows its last value, how long ago it arrived and **Values arriving**. 3. Select **Open the device** (3). The mixer now runs on its own. You can close the wizard tab; the values keep coming. ## Step 7: Look at the device page *Screenshot: The device page of DOCS_TUTORIAL_MIXER_01 showing Connected, the summary figures and the live values of Level, Speed and Temperature* The device page is where you check one machine. At the top you see its place, its name, **Connected**, its profile, gateway and type, then a row of figures: when the last value arrived, how many tags it has, how many reads failed, the response time and the open alarms. 1. The **Live values** tab (1) lists every tag with its value, a small trend, its **Quality** and when it was updated. All three tags show **Good** quality. Watch the values change. 2. **Configure with wizard** (2) opens the same wizard with the device's settings, if you want to change something later. The other tabs show the stored values (**History**), where the data is sent (**Delivery**), connection details (**Diagnostics**) and where the device sits in the plant (**Hierarchy**). [The device page](https://proxus.io/docs/connect/devices/device-page) describes each part. ## Step 8: Draw a trend *Screenshot: The Trend Workspace with the tutorial mixer selected, Temperature and Speed ticked, and both drawn over the last 15 minutes* 1. In the menu, go to **Monitor > Trend Workspace**. 2. In the search box under **Devices** (1), type the device name, then select the device in the list to show its tags. 3. Tick **Temperature** (2) and **Speed**. Each tag is drawn in its own pane on one time axis. 4. Select **15 min** (3) to look at the last fifteen minutes. Temperature draws a smooth wave between 20 and 80 °C; speed wanders up and down. The table under the chart gives the last, minimum, average and maximum value of each tag in the time range. The trend grows as new values arrive; select **Now** to move the range to the present. The small markers along the top of the chart are context, such as changes made in the hub; **Context layers** on the left turn each kind on and off. ## What you have now - A **device**, `DOCS_TUTORIAL_MIXER_01`, read by the **SYSTEM** gateway. - A **device profile**, `Mixer simulator`, that a second mixer can use: in the wizard, pick it under **Start from**, or select **Add one like this** on the device page. - Three **tags**, stored in the historian with their time, and published in the Unified Namespace under `Meridian / Lyon Foods Plant / Processing / Dough / DOCS_TUTORIAL_MIXER_01`. The simulated mixer keeps running until you turn it off. To stop it, open the device page, expand **Configuration**, clear **Active** and select **Save**. ## What's next - [Add a device](https://proxus.io/docs/connect/devices/add-a-device) with a real machine: the same wizard, with an address and a connection test against the machine. - [Simulated devices](https://proxus.io/docs/connect/devices/simulator) lists every pattern and the plant model addresses. - [Unified Namespace](https://proxus.io/docs/concepts/unified-namespace) explains the path your mixer got from its place. - [Rules](https://proxus.io/docs/automate/rules) raise an alarm when, for example, the temperature stays above 75 °C. - [Trend Workspace](https://proxus.io/docs/monitor/trend-workspace) covers saved views, comparisons and context layers. --- # A tour of the hub > What you see after you sign in to the Proxus hub, and what each menu group and main screen is for. Source: https://proxus.io/docs/get-started/tour The hub is the web application you sign in to. Everything you set up in Proxus, and most of what you watch, is here. This page walks through the screen and the menu, so you know where things are before you start. ## The screen *Screenshot: The hub after sign-in: the menu on the left, the tab strip, the Operations Center in the work area and the header icons* 1. **The menu** on the left holds every screen, in seven groups. The **Filter...** box at its top finds a screen by name. The icon at the top left of the header hides and shows the menu. 2. **Tabs.** Each screen you open gets a tab, so you can keep a device, a trend and a rule open side by side and switch between them. Close a tab with its **×**. 3. **The work area** shows the screen of the active tab. 4. **The header icons**, from left to right: **Copilot**, the assistant that answers questions about your plant (also **Ctrl+K**, see [Copilot](https://proxus.io/docs/monitor/copilot)), a link to the Proxus website, a link to this documentation, your user menu (**My Details**, where you change your password, and **Log Off**), and **Settings**, where you choose the language of the interface. Lists in the hub work the same way everywhere: **New** adds an entry, a click opens it, and the toolbar of an open entry has **Save**, **Delete**, **Refresh** and the **Audit Trail** of its changes. ## The menu The groups follow the order of the work: watch the plant, connect machines, organize their data, automate reactions, analyze the history, control access and certificates, and run the platform. What you see depends on your role; an administrator sees every group. ### Monitor: what is happening now | Screen | What it is for | | --- | --- | | **Operations Center** | The start screen: whether everything is within limits, what needs attention, every site and device at a glance, and how data moves through the platform. | | **Trend Workspace** | Draw the values of any tags over time, compare periods, and see machine state, alarms and changes on the same axis. | | **Topology** | A map of the sites, gateways, hub and outbound targets, with their live health. | | **Alerts** | Every alarm that rules and pipelines have raised, to acknowledge and follow up. | | **Copilot** | Ask questions about the plant in plain language; the answers come from live data, with your permissions. | Read more in [Monitor](https://proxus.io/docs/monitor). ### Connect: bring machines in, send data out | Screen | What it is for | | --- | --- | | **Devices** | One entry per machine, PLC, robot or sensor that Proxus reads. | | **Device Profiles** | How to talk to a kind of device: protocol, connection settings and tags. | | **Edge Gateways** | The runtimes that read devices. The hub's own is called **SYSTEM**. | | **Notification Channels** | Ways to reach people: email, SMS, chat services. | | **Outbound Targets** | Databases, brokers and cloud services that receive copies of the data. | | **Import Devices** | Add many devices at once from a spreadsheet. | | **Kepware Project Importer** | Bring devices and tags over from a Kepware project. | Read more in [Connect](https://proxus.io/docs/connect). ### Organize: give the data a structure | Screen | What it is for | | --- | --- | | **UNS Explorer** | The Unified Namespace as a live tree: enterprise, site, area, device, tag. | | **Health Checks** | Findings about how the platform is set up, a map of how its parts depend on each other, and a trace of where a value goes. | | **Application Templates** | Ready-made applications you can install into the hub. | Read more in [Organize](https://proxus.io/docs/organize). ### Automate: react to the data | Screen | What it is for | | --- | --- | | **Pipelines** | Clean, convert, enrich and route values, or react to them, from a goal in plain sentences or on a canvas. | | **Functions** | Your own C# code, run on the gateways you choose. | | **Rules** | Conditions on values or logs that raise alarms and start actions. | | **Rule Actions** | What a rule does when it fires: notify people or trigger an outbound target. | Read more in [Automate](https://proxus.io/docs/automate) and, for the choice between them, [Pipelines, rules and functions](https://proxus.io/docs/concepts/pipelines-and-rules). ### Analyze: look back | Screen | What it is for | | --- | --- | | **Dashboards** | Charts and figures built on the historian and the configuration. | | **Reports** | Printable reports, built in or designed by you. | | **Scheduled Deliveries** | Send reports by email on a schedule. | | **Reporting Federation** | The connection that lets reports and dashboards combine values from the historian with device and alarm data. | Read more in [Analyze](https://proxus.io/docs/analyze). ### Security: who may sign in, and the certificates | Screen | What it is for | | --- | --- | | **Users** and **Roles** | Who may sign in, and what each role may see and change. | | **Certificate Store** | The platform's certificate authority and every certificate the hub, the gateways, OPC UA connections and outbound targets use. | Read more in [Administer](https://proxus.io/docs/administer). ### Platform: run Proxus | Screen | What it is for | | --- | --- | | **My Profile** | Your own account. | | **Demo Data** | Load example plants to try Proxus. | | **White Labeling** | Your own title, logo and styling on the hub. | | **License Info** | The license of this installation and what it allows. | | **Config Editor** | The configuration file of the platform. | | **System Logs** | What the hub and the gateways have logged. | | **Database Health** | A report on the state of the databases. | Read more in [Administer](https://proxus.io/docs/administer). ## What's next - [Connect your first machine](https://proxus.io/docs/get-started/first-machine) to see these screens fill with your own data. - [How Proxus is built](https://proxus.io/docs/concepts/architecture) explains what runs where behind these screens. --- # Concepts > How Proxus is built and how its parts work together, from the edge gateway next to a machine to the historian, the namespace and automation. Source: https://proxus.io/docs/concepts The pages in this section explain Proxus rather than tell you what to click. Read them when you want to know why a screen asks for something, where a value is at a given moment, or which tool fits a job. The how-to guides link here for background. ## The building blocks in one picture A machine is read by an **edge gateway**. The gateway publishes every value in the **Unified Namespace**, sends it to the **outbound targets** you chose, and passes it to the **hub**, which keeps its history and shows it. **Pipelines**, **rules** and **functions** act on the values on their way. ## Pages in this section The [glossary](https://proxus.io/docs/reference/glossary) defines every term in a sentence or two. --- # Architecture > The hub and the edge gateways, how they talk to each other over a message server, what each one does, and where Proxus keeps its data. Source: https://proxus.io/docs/concepts/architecture Proxus has two kinds of runtime: one **hub** and any number of **edge gateways**. The hub is where people work and where the history is kept. The gateways sit close to the machines and do the reading. A message server carries everything between them. ## The hub The hub is the web application you sign in to, together with the services behind it. It: - keeps the **configuration** of the whole installation: gateways, devices, device profiles, rules, pipelines, functions, users and roles; - sends each gateway the part of the configuration it needs, and tells it when something changes; - receives the values of the devices that deliver to the historian (every new device does) and writes them to the **historian**; - shows live values, trends, dashboards and reports, and keeps the alarms; - sends notifications to people (email, SMS, chat) when a rule asks for it; - checks the license and serves the REST API. There is one hub per installation. In the Docker Compose stack it is the `proxus-ui` service. ## Edge gateways An edge gateway is the Proxus runtime that talks to machines. It: - reads devices with their protocol, at the interval set for each device, and receives values that devices send over MQTT or HTTP; - gives every value its time and quality; - runs the pipelines, rules and functions assigned to it; - publishes the values in the Unified Namespace on its own MQTT broker; - sends the values to the outbound targets of each device, and queues them while a target cannot be reached; - passes the values to the hub, and keeps them while the hub cannot be reached. A gateway keeps no configuration of its own. When it starts, or when its connection comes back, it receives its devices, pipelines, rules and functions from the hub. You set up everything in the hub, and a gateway that is replaced or restarted picks up where the old one stopped. ### The SYSTEM gateway Every installation has one gateway called **SYSTEM**, which runs next to the hub (the `proxus-server` service in the compose file). It reads machines on the hub's own network, and it runs the simulator. New rules and functions run on SYSTEM unless you choose other gateways. ### Remote gateways For machines on another network or at another site, you install a gateway near them. Each remote gateway runs together with a small message server of its own. That message server connects to the hub's message server on port `7422`, over TLS. The connection is opened from the gateway's side, so a gateway needs one outgoing connection to the hub, and nothing on the plant network has to accept connections from the hub. [Install an edge gateway](https://proxus.io/docs/connect/edge-gateways/install-a-gateway) shows how. ## How the hub and gateways talk All traffic between the hub and the gateways goes through a message server (NATS, the `hub-server` service in the compose file). Values, configuration changes, status, logs and alarms each travel as messages. - **Messages wait for their receiver.** The message servers store messages on disk for a limited time, so a receiver that is offline gets them later. A configuration change made while a gateway is offline reaches it when it is back; values read while the hub is out of reach reach the hub later. [How data flows](https://proxus.io/docs/concepts/data-flow) describes this buffer. - **Each gateway has its own identity.** On its first start the hub creates the security settings of the message server. Each gateway is enrolled with its own key; there is no shared password between gateways. - **Every connection is encrypted.** The message server uses TLS on all its ports, and every connection checks the server's certificate against the platform's certificate authority in the [Certificate Store](https://proxus.io/docs/administer/certificates). - **The gateway confirms what it applied.** After a gateway applies a change (a new device, a changed rule), it reports back, so the hub can show whether the change is running. ## Where data is kept | What | Where | Service in the compose file | | --- | --- | --- | | Configuration: devices, profiles, rules, pipelines, users, alarms | PostgreSQL database | `postgresql` | | Every value with its time (the historian), and the system logs | ClickHouse database | `clickhouse` | | Values and messages on their way, and each gateway's buffer | The message servers' storage | `hub-server`, and each remote gateway's own message server | | The configuration file `Proxus-config.toml` | The `config` volume | shared by `proxus-ui` and `proxus-server` | Copies of the data also go to the [outbound targets](https://proxus.io/docs/connect/outbound-targets) you configure: your own databases, message brokers and cloud services. ## What's next - [How data flows](https://proxus.io/docs/concepts/data-flow) follows one value through these parts. - [Install Proxus with Docker](https://proxus.io/docs/get-started/install) sets up the hub and the SYSTEM gateway. - [Run Proxus on Kubernetes](https://proxus.io/docs/operate/kubernetes) covers larger installations. --- # How data flows > The path of one value from the machine through the gateway, the namespace, the outbound targets and the historian, and what happens when a link is down. Source: https://proxus.io/docs/concepts/data-flow This page follows one value, the temperature of a mixer, from the machine to a report. It explains what happens at each stage and where the value is if something on the way is not reachable. ## 1. Read The edge gateway assigned to the device reads it. How depends on the protocol: - **Polled protocols** (Modbus, Siemens S7, EtherNet/IP and many others): the gateway asks the device for all its tags at the device's **Read every** interval. - **Devices that send by themselves** publish to the gateway's MQTT broker or post to its HTTP endpoint. Each device has its own token to prove who it is. - **The simulator** makes values on the gateway itself. The gateway gives each value its **time** (when it was read) and its **quality**: **Good** when the read worked, **Bad** when it failed. A device that keeps failing is not polled at full speed: the gateway tries it again at growing intervals until it answers, so one unreachable machine does not slow the others down. ## 2. Shape Before the value goes anywhere, the gateway lets your own logic change it: - **Functions** on the gateway see each value first. - **Pipelines** that shape data run next, in the order you set: convert a unit, scale a value, rename a tag, add context, drop a value or route it. What comes out of them is what every later stage receives. Then the gateway compares the values with the previous ones and marks which have changed. Pipelines that react to data (raise an alarm, notify, write to a device) and the **rules** of the gateway work on this result. [Pipelines, rules and functions](https://proxus.io/docs/concepts/pipelines-and-rules) explains the difference. ## 3. Publish and route From the gateway, the value goes three ways at once: - **The Unified Namespace.** The gateway publishes the value on its built-in MQTT broker, under the place of the device, for example `v1/Meridian/Lyon_Foods_Plant/Processing/Dough/DOCS_TUTORIAL_MIXER_01/telemetry/Temperature`. Any MQTT client with access can subscribe. See [Unified Namespace](https://proxus.io/docs/concepts/unified-namespace). - **Outbound targets.** Each target ticked on the device receives the value from the gateway. A target's **Transport Strategy** decides what it gets: every value (**Pass Through**), only values that changed (**On Change**), or only what pipelines send to it (**Pipelines Only**). - **The hub.** The historian, called **SYSTEM INTERNAL DB** in the device's target list, receives the value. Every new device has it in its list; a device removed from it has no history. The gateway hands the value to the message server, which brings it to the hub. ## 4. Buffer A remote gateway does not send values straight to the hub. It first stores them with its own message server, on the gateway's disk, and the hub copies them from there. While the link to the hub is down, or the hub is stopped, values keep collecting on the gateway. When the link is back, the hub receives what it missed, with the times the values were read, so the history has no gap. - How long the gateway keeps values it could not deliver is set per gateway: **Buffer Retention (hours)** on the gateway, 48 hours by default, from 1 to 720. Values older than that are dropped, oldest first. - The gateway needs disk for that many hours at its data rate. - The **SYSTEM** gateway runs next to the hub, so it has no buffer setting. Alarms and notifications raised on a remote gateway are buffered the same way: the gateway keeps each one until the hub confirms it has it, and sends them in the order they were raised. > **Note:** The buffer protects the way to the hub. Outbound targets have their own durable queue on the gateway: data for a target waits there while the target is unreachable, for the same **Buffer Retention (hours)**, and is written in order when the target is back. The target's status on the [Outbound Targets](https://proxus.io/docs/connect/outbound-targets) screen shows whether it is delivering and how many messages are waiting. ## 5. Store and show At the hub, the value: - is written to the **historian** (the ClickHouse database), with the device, the tag, its unit and its time; - updates the **live views**: the device page, the UNS Explorer, the Operations Center; - becomes available to the **Trend Workspace**, **Dashboards** and **Reports**, which read the historian. By default the historian keeps every value. A retention period can be set in the configuration; see [Configuration](https://proxus.io/docs/administer/configuration). ## The other direction: configuration Configuration flows from the hub to the gateways along the same path. When you save a device, the hub sends it to the device's gateway; the gateway applies it and confirms. The verify step of the device setup wizard shows these stages as **Saved**, **Sent to** the gateway, **Device connected** and **First values**. A gateway that is offline receives the change when it connects again, and a gateway that starts receives its full configuration from the hub. ## What's next - [Architecture](https://proxus.io/docs/concepts/architecture) describes the hub, the gateways and the message server. - [Data is missing](https://proxus.io/docs/troubleshoot/data) helps when a value does not arrive where you expect it. --- # Devices, profiles and tags > What a device, a device profile and a tag are in Proxus, how they relate, and what the data types and quality of a value mean. Source: https://proxus.io/docs/concepts/devices-profiles-tags Three objects describe every machine Proxus reads: the **device** (this machine), the **device profile** (how to talk to machines of its kind) and its **tags** (the values to read). Splitting them this way lets you describe a kind of machine once and add the tenth one in a minute. ## Device A **device** is one machine, PLC, robot, meter or sensor that Proxus reads. It holds what is particular to that one machine: | Part | Meaning | | --- | --- | | **Device name** | Unique in the installation. Most plants use site, line and equipment, such as `LYS_MIXER_03`. | | Address | Where the machine is on the network (IP address and port), and the reading interval if it differs from the profile. | | **Gateway** | The one edge gateway that reads it. | | **Device profile** | The one profile it uses. | | Place | **Enterprise**, **Site**, **Area**, **Process cell** and **Equipment module**. All optional. The place sets the device's path in the [Unified Namespace](https://proxus.io/docs/concepts/unified-namespace) and how lists group devices. | | **Device type** | What the machine is (Mixer, Pump, Filler / Packaging...). It sets the icon and how the Operations Center shows the device. You choose it; Proxus does not guess it. | | Outbound targets | Where its values go besides the historian. | | **Active** | Whether the gateway reads it. Clear it to stop reading without deleting the device. | A device belongs to exactly one gateway and one profile. To read the same machine from two gateways, add two devices. ## Device profile A **device profile** says how to talk to a kind of device: - the **protocol** (Modbus TCP, Siemens S7, OPC UA, MTConnect, the simulator...); - the **connection parameters** of that protocol (byte order, unit ID, rack and slot, security...); - the list of **tags**. Many devices can share one profile. A change to the profile, such as a new tag, applies to every device that uses it; the profile's **Used By** list shows which ones. The device setup wizard creates a profile when you add a device, under the **Profile name** you give it, and offers it under **Start from** the next time. ## Tag A **tag** is one value read from a device: a temperature, a speed, a counter, a state. Each tag in a profile has: | Field | Meaning | | --- | --- | | **Name** | The name the value has everywhere in Proxus: on the device page, in trends, in the UNS topic. | | **Address** | Where the value is in the device, in the protocol's own form: a register (`x=3;0` for Modbus holding register 0), a Siemens address (`M10`), an OPC UA node, or a range such as `[0,100]` for the simulator. | | **Type** | The data type the device holds the value in. See the table below. | | **Unit** | The engineering unit (`°C`, `rpm`, `%`), shown next to the value and published with it. | | Polling interval | A reading interval for this tag only. Empty or 0 uses the profile's interval. | ## Data types The data types a tag can have. The first name is the one used in Proxus, the second the IEC 61131-3 name a PLC programmer uses. | Type | IEC 61131-3 | Size | | --- | --- | --- | | Bool | BOOL | 1 bit | | Short | INT | 16 bit | | UShort | UINT | 16 bit | | Int | DINT | 32 bit | | UInt | UDINT | 32 bit | | Float | REAL | 32 bit | | Long | LINT | 64 bit | | ULong | ULINT | 64 bit | | Double | LREAL | 64 bit | | String | STRING | variable | | Bytes | ARRAY OF BYTE | variable | | DateTime | DATE_AND_TIME | | Choose the type the device stores the value in, not the type you would like to see. A `Float` read as `Int` gives a wrong number. To convert or scale a value, use a [pipeline](https://proxus.io/docs/concepts/pipelines-and-rules). ## Quality Every value carries a quality, shown in the **Quality** column of the device page and stored with the value: | Quality | Meaning | | --- | --- | | **Good** | The gateway read the value and it is current. | | **Bad** | The read failed. The value field holds the reason, for example a wrong address or a timeout. | | **Uncertain** | The tag failed several reads in a row, so the gateway set it aside. It tries the tag again from time to time, and the value shows the last error. | A tag with **Bad** or **Uncertain** quality does not stop the other tags of the device; they keep being read. When the whole device does not answer, the gateway marks the device as not connected and tries it again at growing intervals. ## What's next - [Add a device](https://proxus.io/docs/connect/devices/add-a-device) with the setup wizard. - [Device profiles](https://proxus.io/docs/connect/device-profiles) explains how to edit a profile and its tags. - [Wrong values or bad quality](https://proxus.io/docs/troubleshoot/devices) helps when tags do not read well. --- # Unified Namespace > How Proxus builds the Unified Namespace from the place of each device, the MQTT topics it publishes, and what the messages contain. Source: https://proxus.io/docs/concepts/unified-namespace A **Unified Namespace** (UNS) is one shared, structured place where every current value of the plant can be found by its location: this enterprise, this site, this area, this machine, this value. Any system that needs plant data subscribes to the namespace, instead of connecting to each machine or to each other. Proxus builds the namespace for you. Every device you add is published in it, under the place you gave it, and every tag value appears there as it is read. ## The place of a device The levels of the namespace follow ISA-95, the international standard for the structure of a manufacturing enterprise. You set them on each device, in the device setup wizard or on the device page: | Level | Example | What it usually is | | --- | --- | --- | | **Enterprise** | `Meridian` | The company. | | **Site** | `Lyon Foods Plant` | One plant or location. | | **Area** | `Processing` | A department or hall in the plant. | | **Process cell** | `Dough` | A line or a group of machines that work together. | | **Equipment module** | `Kneading` | A part of a machine, when one device stands for part of a larger unit. | All levels are optional. A level you leave empty is skipped, so a device with only a site is published directly under that site. The place also groups devices in lists, the Trend Workspace and the Operations Center, so it is worth agreeing on names before you add many devices. ## Topics Proxus publishes the namespace over MQTT. Each value has its own topic, built from the place, the device name and the tag name: ```text v1///////telemetry/ ``` For the mixer from [Connect your first machine](https://proxus.io/docs/get-started/first-machine): ```text v1/Meridian/Lyon_Foods_Plant/Processing/Dough/DOCS_TUTORIAL_MIXER_01/telemetry/Temperature ``` - `v1` is the version of the topic structure. - Empty levels are left out; there is no empty segment. - In each level, any character other than a letter, a digit, `_` or `-` becomes `_`. A space in `Lyon Foods Plant` becomes `Lyon_Foods_Plant`. Upper and lower case are kept. Besides one topic per tag, each device has three more: | Topic | Content | Sent | | --- | --- | --- | | `...//telemetry/` | One value of one tag. | Every time the tag is read. | | `...//telemetry/_summary` | The latest value of every tag of the device in one message, with the device's place. | At most every 5 seconds by default. | | `...//state/_lastSeen` | When the device last sent a value. | At most every 5 seconds by default; kept by the broker for new subscribers. | | `...//state/_status` | Whether the device is online. | When the status changes; kept by the broker for new subscribers. | A new subscriber therefore sees the status and the last-seen time of every device at once, and the values as they come in. ## Messages Messages are JSON by default. A value message looks like this: ```json { "ts": "2026-10-15T19:12:35.120Z", "value": 62.5, "dataType": "Float", "unit": "°C", "quality": "Good", "source": "Proxus" } ``` | Field | Meaning | | --- | --- | | `ts` | When the value was read, in UTC. | | `value` | The value, as a JSON number, true or false, or text. | | `dataType` | The type of the value (`Bool`, `Int`, `Float`, `Double`, `String`...). It is worked out from the value itself, so it can differ from the tag's type: a `Float` tag that reads `62` is published as `Int`. | | `unit` | The tag's unit. Left out when the tag has none. | | `quality` | In this version always `Good`. The real quality of each value is on the device page and in the historian. | | `source` | Always `Proxus`. | Proxus can publish the namespace as **Sparkplug B** instead of JSON, for systems built on that standard. The format, the summary interval and the other publishing settings are in the `[UNS]` section of the configuration file; see [Configuration keys](https://proxus.io/docs/reference/configuration). ## Where the namespace is published Each edge gateway publishes the values it reads on its own built-in MQTT broker. For the **SYSTEM** gateway in the Docker Compose stack, that broker listens on port `1883` of the hub host. A remote gateway has its own broker, on the port chosen when it was installed. Subscribers need credentials; the broker does not accept anonymous clients by default. [MQTT and the UNS topics](https://proxus.io/docs/develop/mqtt) shows how to connect and subscribe. In the hub, **Organize > UNS Explorer** shows the whole namespace as a live tree, with the values of every gateway together. ## What's next - [UNS Explorer](https://proxus.io/docs/organize/uns-explorer) to browse the namespace in the hub. - [UNS permissions](https://proxus.io/docs/administer/uns-permissions) to decide who may see which part of it. - [Devices, profiles and tags](https://proxus.io/docs/concepts/devices-profiles-tags) for the objects behind each topic. --- # Pipelines, rules and functions > The three ways to act on data in Proxus, what each is for, where it runs, and how to choose between them. Source: https://proxus.io/docs/concepts/pipelines-and-rules Proxus gives you three tools to do something with the values it reads. They overlap a little, but each has a job it does best: - A **pipeline** changes values on their way, or reacts to them. You start it from a goal in plain sentences, or build it from steps on a canvas. - A **rule** watches values or logs for a condition and raises an alarm when it is met. - A **function** is your own C# code, for what the other two cannot express. All three are set up in the hub, under **Automate**, and run on the edge gateways you choose, next to the data. A new rule or function runs on the **SYSTEM** gateway until you pick others. ## Pipelines A pipeline is a chain of steps you build on a canvas, or start from a goal in the gallery and adjust. A pipeline does one of two things: - **Shape the data on its way.** It runs on every matching value before the value is stored, published or sent anywhere: convert a unit, scale a raw count, rename a tag, add context, check the quality, drop or route a value. Everything after it (the historian, the Unified Namespace, the outbound targets, the rules) receives the shaped value. - **React to the data.** It runs after shaping, on the final values, and also on device and gateway events, logs and schedules: raise an alarm when a value stays out of range, notice that a device has gone silent, send a value to a target, write to a device. A pipeline is not tied to one device. It chooses the values it works on by device, profile, protocol, place, tag or other properties, so a single pipeline can cover every filler in a plant, including fillers added later. Pipelines are published in two stages: 1. **Publish in Shadow** runs the pipeline on its gateways and records what it would do, without changing data, opening alarms or writing to devices. 2. **Publish Active** lets it take effect, once Shadow has shown the right results. Steps that write to a device or call an outside API only take effect on gateways where these effects are turned on in the configuration (`[Flows]`, `EffectsEnabled`); they are off by default. Use a pipeline when the logic can be drawn as steps, when it must change the data itself, or when it should apply to many devices at once. See [Pipelines](https://proxus.io/docs/automate/pipelines). ## Rules A rule is a condition with consequences. It checks the values, device status changes and log entries on its gateways and, when the condition is met, raises an **alert** that operators see in **Monitor > Alerts** and can acknowledge. A rule's condition is either: - an **expression** on values, such as "Temperature greater than 60", or - **anomaly detection**, which learns how a tag normally behaves and flags a sudden jump, a fast rise or fall, a slow drift, a value that stops moving (flatline), or a gap in the data. What happens next is set by **Rule Actions**: send a notification through a notification channel, or trigger an outbound target. The same detector runs in the Trend Workspace, so an anomaly you see on a trend can be turned into a rule that behaves the same way. Use a rule when the question is "tell someone when this happens". Rules do not change the data. See [Rules](https://proxus.io/docs/automate/rules) and [Rule actions](https://proxus.io/docs/automate/rule-actions). ## Functions A function is a C# class you write in the hub. The hub compiles it and sends it to the gateways you choose, where it runs for as long as it is deployed. A function can: - see every value the gateway reads, before pipelines do; - run on a schedule; - subscribe and publish to MQTT topics; - read from a database and save the result as values of a device; - send values back into the data flow, where pipelines, rules and targets treat them like any other value. Use a function for logic that needs real code: a calculation over many devices, or a system Proxus has no connector for. A function is more powerful than a pipeline, but it is code you maintain. See [Functions](https://proxus.io/docs/automate/functions) and the [functions SDK](https://proxus.io/docs/develop/functions-sdk). ## Choosing | You want to | Use | | --- | --- | | Convert, scale, rename or filter values before they are stored and published | A pipeline that shapes data | | Raise an alarm when a value crosses a limit | A rule, or a pipeline that reacts to data | | Spot unusual behaviour without setting a limit | A rule with anomaly detection | | Notify someone by email, SMS or chat | A rule with a notification action | | Notice that a device stopped sending | A pipeline that reacts to data | | Send selected values to one system only | A pipeline that sends to an outbound target set to **Pipelines Only** | | Combine data from several devices, or reach a system Proxus has no connector for | A function | ## Where they run in the flow On a gateway, a value meets them in this order: functions see the value first, then pipelines that shape data, then the gateway marks changed values, and then rules, pipelines that react and the outbound targets work on the result. [How data flows](https://proxus.io/docs/concepts/data-flow) follows a value through these stages. ## What's next - [Pipelines](https://proxus.io/docs/automate/pipelines): build your first pipeline and publish it in Shadow mode. - [Rules](https://proxus.io/docs/automate/rules): raise an alarm when a value crosses a limit. - [Functions](https://proxus.io/docs/automate/functions): run your own C# code on the edge gateways. --- # Monitor > Watch the plant live. See what needs attention, follow tag values over time, find where data stops and handle alarms. Source: https://proxus.io/docs/monitor **Monitor** is where you look when you want to know whether the plant is running and, if it is not, where and why. These screens only read: nothing you do here changes how a machine is read, except acknowledging or closing an alarm and saving your own trend views. In the hub, they are in the **Monitor** menu. ## The screens | Screen | What it answers | | --- | --- | | **Operations Center** | Is anything wrong right now, where, and what should I do? One page for alarms, silent gateways, devices without data and the flow of data through the hub. | | **Trend Workspace** | How did these values change? Tags of one or more devices on one time axis, with alarms, changes and machine state next to the line. | | **Topology** | Where does the data come from and where does it stop? A map of sites, lines, devices, gateways and outbound targets, coloured by health. | | **Alerts** | Which alarms are open, who took them and how were they closed? The list of every alarm that rules and pipelines raised. | | **Copilot** | Can you explain what is going on? Ask in plain language; Copilot reads devices, gateways, alarms and health checks with your permissions. | ## How they work together A typical shift starts in the **Operations Center**. A problem there leads to one of the other screens: an alarm opens in **Alerts**, a device without data is found on the **Topology** map, and a value that looks wrong is compared with yesterday in the **Trend Workspace**. ## Screens ## Common tasks --- # Operations Center > What the Operations Center shows. The verdict, the Needs attention list, the fleet, the data pipeline and the events of the last changes. Source: https://proxus.io/docs/monitor/operations-center The **Operations Center** answers three questions in order: is anything wrong, where, and what should you do. It is the first item of the **Monitor** menu. The page refreshes by itself; **Live** and **Updated** in the top right corner show when it last did. The page keeps normal things grey. Only something that needs you gets a colour and a place in the list. *Screenshot: The Operations Center with the verdict at the top, one open alarm and one note in Needs attention, and the fleet with three sites* 1. **Verdict**: one line that sums up the hub. **All systems within limits** when nothing needs you, otherwise the number of issues and what they are. 2. **Needs attention**: the open alarms and system problems, worst first. 3. **Counts**: sites, gateways, devices and delivery targets, each with a short note when something is wrong. 4. **Fleet**: one row per site with one cell per device. 5. **Data flow map**: opens a full-screen map from each gateway to its devices and their targets. ## Verdict When nothing needs attention, the verdict lists how many devices are sending data, the values per second and the latency, that there are no open alarms, and how many notes are below. When something needs attention, it says how many issues there are and lists them. Its colour follows the worst item: amber for a warning, red for a critical issue. ## Needs attention The list holds real alarms and problems the hub finds by itself, in one list. Critical items come first; within the same level, the oldest comes first, because it has waited longest. Each item has a level badge (**CRIT**, **WARN** or **NOTE**), a title, where it is, how long ago it started and the buttons that fit it. | Item | When it appears | Buttons | | --- | --- | --- | | An open alarm | A rule or a pipeline raised an alarm that nobody has acknowledged yet. The age shows **unacknowledged**. | **Acknowledge** takes the alarm. **Open** opens it on the alarm page. | | **Gateway … is silent** | An edge gateway stopped reporting. Its devices are not counted again as devices without data. | **Probe** sends a test message to the silent gateways and shows which ones answer. **Gateways** opens the gateway list. | | **… devices are not sending data** | Enabled devices that sent no data, for a reason other than a silent gateway. It is a **NOTE** while fewer than 5% of the devices are affected, and a warning above that. | **Check** lists the devices without an active stream and the last error of each. **Devices** opens the device list. | | **No device is sending data** | There are devices, but none of them sends data. | **Check**, **Devices** | | Critical log entries, or errors logged in the last minute | At least one critical log entry, or five or more errors, in the last minute. | **Open logs** opens **System Logs**. | | **License capacity near its limit** or **exceeded** | A gateway's outbound data points per second are close to, or above, what the license allows. Above the license, outbound data points are dropped. | **Gateways** | | **Streaming devices have no delivery target** | Devices send data, but no device has a target, not even the historian (**SYSTEM INTERNAL DB**). Values are visible live, but are not forwarded or stored. | **Targets** opens the outbound targets. | **Check** and **Probe** only look; they do not restart or change anything. Their result stays under the item until the page is opened again. Below the list, **… acknowledged, in follow-up** opens the alarms someone has acknowledged but not closed yet, with who took each one and when. Select one to open it. **All alarms** opens the **Alerts** list. ## Fleet | Count | What it shows | | --- | --- | | **Sites** | Sites with no issue, out of all sites. **No site assigned** is listed below but not counted as a site. | | **Gateways** | Connected gateways, out of all gateways. | | **Devices** | Devices sending data, out of all devices. | | **Delivery** | Active outbound targets. | Select a count to open the matching list. Below the counts, each site has a row: its gateways and devices, a cell per device and a short state such as **Normal** or **1 device without data**. A grey cell is a device sending data, an amber cell a device without data, and a striped cell a device behind a silent gateway. A site with very many devices shows a bar with the share of devices sending data instead of cells. With more than eight sites, the panel shows one tile per site and lists only the sites with problems. **Data flow map** opens a full-screen tree: each gateway, the devices it reads and the targets their data goes to. Select **Close** to go back. ## Data pipeline *Screenshot: The Data pipeline section with ingest, processing and delivery, the values per second chart with an alarm marker, and the Events list below* 1. **Ingest**, **Processing** and **Delivery**: the three stages of the data. Ingest shows the values per second, the latency, how many devices send data and the protocols in use. Processing shows the active rules and functions and the open alarms. Delivery lists up to five active outbound targets and how many devices each one receives. 2. The chart: values per second and latency over the time shown next to the section title (up to the last hour). A dashed line marks the moment an alarm was raised. The chart appears after the first minute of data. 3. **Events**: see below. ## Events **Events** lists the latest changes of state: alarms raised, acknowledged, resolved or ignored, gateways that went silent or reconnected, devices that stopped or resumed sending data, license capacity changes and error bursts. Each line has the time, the kind (**Alarm**, **Connectivity**, **Delivery**, **Capacity** or **System**), the message and, for alarms, who changed it. **Logs** opens **System Logs**. > **Note:** Changes that were not stored as alarms, such as a gateway going silent, are only listed from the moment the page was opened. If nothing changed since then, the list says so. ## What's next - [Find what stopped](https://proxus.io/docs/monitor/find-what-stopped): follow a warning to the device and its error. - [Acknowledge and resolve an alert](https://proxus.io/docs/monitor/acknowledge-an-alert) - [Topology](https://proxus.io/docs/monitor/topology): the same health, drawn as a map. --- # Trend Workspace > The Trend Workspace: tags of several devices on one time axis, comparison periods, context layers, notes, saved views, export and presentation mode. Source: https://proxus.io/docs/monitor/trend-workspace The **Trend Workspace** charts stored tag values from the Proxus historian. Tags of one or more devices share one time axis, each tag in its own pane, so you can see what several machines did at the same moment. It is in **Monitor > Trend Workspace**. You can also reach it from other screens: **Open in workspace** on an alarm page, and on the trend panel that **Open trend** opens in the UNS Explorer and on the device page. Each of these opens the workspace with that tag and time range. *Screenshot: The Trend Workspace with the Speed tags of two fillers over 8 hours, the range buttons, the compare list, saved views and the figures table* 1. **Time range**: the range buttons and the arrows. 2. **Compare**: lays an earlier period over the chart. 3. **Saved views**: open, save and delete views. 4. The chart: one pane per tag, with the tags' colours in the legend. 5. The figures table: one row per tag. ## Choosing tags The **Devices** panel on the left lists the devices you may read, grouped by site and area. Type in **Search devices or plant areas** to narrow the list. Select a device to list its tags, then tick the tags to chart. A tag appears in the list when it has data in the last 7 days. The number next to a device is how many of its tags are on the chart. At most 8 tags can be on the chart at once. Remove a tag with its × in the table or by clearing its tick box. ## Time range | Control | What it does | | --- | --- | | **15 min**, **1 h**, **8 h**, **24 h**, **7 days** | Shows that much time up to now. | | **‹** and **›** | Moves the range one range width earlier or later. | | **Now** | Goes back to a range that ends now. | The range and the time zone are shown at the top left. Times are shown in your browser's time zone. Inside the chart, scroll with the mouse wheel or drag the handles of the slider under the chart to zoom into part of the range. All panes zoom together. Over long ranges, the chart does not draw every stored value. It draws the average with the minimum and the maximum of each time step instead. The **Data** column of the table says which: **Raw** with the number of samples, or the step (for example **1m avg + min/max**) with the number of samples. ## Compare **Compare** draws an earlier period as a dashed grey line in each pane: | Option | Earlier period | | --- | --- | | **Off** | No comparison. | | **Previous period** | The range just before the one shown, of the same length. | | **Same time yesterday** | The same range, one day earlier. | | **Same time last week** | The same range, seven days earlier. | The table gets a column with the earlier period's average and the change in percent. ## The figures table | Column | Meaning | | --- | --- | | **Tag** | The tag and its device. | | **Last** | The last value in the range. | | **Min**, **Max** | The lowest and highest value in the range. | | **Avg** | The time-weighted average: each value counts for as long as it held. Gaps in the data are left out. | | **Total** | Shown when **Show total over time** is ticked: each value multiplied by how long it held, added up. For a rate this is the amount (kW gives kWh, m³/h gives m³). It is not meaningful for other tags. | | **Data** | How the values were drawn: raw or averaged, and the number of samples. | **Export** with **CSV** or **Excel** downloads what the chart shows. See [Export a trend](https://proxus.io/docs/monitor/export-a-trend). ## Context layers and events The workspace shows what happened around the charted devices, from what the platform already records: *Screenshot: The Context layers list with Machine state, Alarms, Platform changes, Edge gateway connection and Notes ticked* | Layer | What it shows | | --- | --- | | **Machine state** | A coloured band above each pane, from the device's state band. See [Show machine state on a trend](https://proxus.io/docs/monitor/show-machine-state). | | **Alarms** | Alarms raised for the charted devices. | | **Platform changes** | Changes to the devices, and to the gateways, rules and functions they run on, and pipelines published to their gateways, with who made them. | | **Edge gateway connection** | When the devices' gateway connected or disconnected. | | **Notes** | Notes that users pinned to a moment. | Each event is a marker above the panes and a dashed line through them. Untick a layer to hide its events. *Screenshot: The In this range list with platform changes, each with a time, a kind and who made it, and the Add a note button at the bottom* 1. **In this range**: the number of events in the range. 2. An event. Select it to zoom the chart to that moment. 3. **+ Add a note**: write a **Note**, click the chart to pin it to a moment (otherwise it is pinned to now or the end of the range), choose the device if several are charted, and select **Save**. Everyone who charts that device sees the note. ## Saved views and links A view is the set of tags, the range, the comparison and the layers. - **Save view** asks for a **View name**. Tick **Share with everyone** to let other users open it. Saving under a name you already used replaces that view. - **Saved views…** lists your views and the views others shared, shown as "name (owner)". Choosing one opens it. - **Delete view** appears when one of your own views is open. Shared views of others cannot be deleted by you. - **Copy link** copies an address that opens the same view. The person who opens it needs access to the same devices. ## Presentation mode **Presentation mode** shows the first tag of the chart large on a dark screen that refreshes by itself, for a screen on the shop floor. The address it opens can be bookmarked to open the presentation directly. *Screenshot: Presentation mode on a dark screen with the current speed, the machine state Running, three stops in the last 8 hours and no open alarms above a large chart* 1. The tiles: **Now** (the current value), **Machine state** and for how long, **Stops** in the range (the time spent in states coloured **Stopped / fault**), and **Open alarms** of the device. 2. **Exit (Esc)** goes back to the workspace. Machine state and stops need a state band on the device. The range follows the workspace's range button; a custom range is shown as the last hour. ## What's next - [Compare tags over time](https://proxus.io/docs/monitor/compare-tags) - [Export a trend](https://proxus.io/docs/monitor/export-a-trend) - [Show machine state on a trend](https://proxus.io/docs/monitor/show-machine-state) --- # Topology > What the Topology screen shows. The plant, fleet and flow views of sites, devices, gateways and targets, the inspector, and the replay of the last hour. Source: https://proxus.io/docs/monitor/topology **Topology** draws the plant as a map: sites, areas and lines with their devices, the edge gateways that read them, the Proxus hub and the outbound targets that receive the data. Everything is coloured by health, so you can see where data stops. It is in **Monitor > Topology** and updates by itself. *Screenshot: The Topology screen with the Plant view of all sites, the KPI row above and the All sites inspector on the right* 1. The views: **Plant**, **Fleet** and **Flow**. 2. **Issues lens** fades everything that is healthy. **Live flow**, next to it, animates the data moving along the links. 3. **Jump to a site, line or device**: type a name and choose a result to go to it on the map. 4. The figures: **devices**, **devices live**, **gateways silent**, **values / min at the hub**, **hub latency** and **devices with issues**. The small lines show the recent rate and latency. 5. The inspector: what is selected, its counts and the devices that need attention. ## Health colours | Colour | Name | Meaning | | --- | --- | --- | | Green | **Healthy** | The device sends data and reports no problem. | | Amber | **Needs attention** | The device sends data but warns or retries, or a group has devices with issues. | | Red | **Down** | The device reports an error. | | Grey | **No data** | No data arrives from the device. | | | **Disabled** | The device is switched off. | A solid link means the **gateway polls** the device; a dashed link means the **device pushes** its data to Proxus. ## Views **Plant** is the isometric map. It starts at **All sites**. Double-click a site, area or line to step into it; the breadcrumbs at the top of the map lead back, as does **Back to …**. The zoom buttons and **Fit to screen** sit at the bottom right. A level with too many items shows **+…** for the rest; use search or the **Issues lens** to find one. **Fleet** shows one column per site. The tallest columns have the most devices with issues. **Flow** shows the data as bands from devices (or sites, areas and lines) through the edge gateways and the hub to the outbound targets. The width of a band is the number of values stored per minute over the last 5 minutes. When nothing has been stored yet, the width is the number of devices. A cross marks a place where the data stops. *Screenshot: The Flow view of the Dough line with eight mixers feeding the SYSTEM gateway, the Proxus Hub and SYSTEM INTERNAL DB* ## The inspector Click anything on the map to select it. The inspector on the right shows it, and the map dims everything that is not on its data path. | Selected | What the inspector shows | | --- | --- | | A site, area or line | Its devices by health, its gateways and targets, and up to five devices with issues, worst first. Select one to go to it. **Step into …** opens the level. | | A device | Its state and last message, **Where**, **Gateway**, **Protocol**, **Data** (gateway polls or device pushes) and **Targets**. **Open device** opens the device page. | | An edge gateway | Its sites, **Last heartbeat**, reads per minute, memory, the devices behind it and the rules on it. **Depends on it** lists what stops if the gateway stops. **Open gateway** opens it. | | The **Proxus Hub** | Values per minute, latency, gateways, devices and targets. | | An outbound target | The devices feeding it, how many of them have issues and the gateways the data comes through. | When a gateway goes silent, the inspector says so: the devices behind it went quiet with it, so the gateway host or its link to the hub is the likely cause, not the devices. ## The last 60 minutes *Screenshot: The timeline of the last 60 minutes, one bar per minute showing how many devices wrote data, with the Live badge* 1. One bar per minute: how many devices wrote data to the Proxus historian in that minute. A line marks a minute where devices stopped reporting or came back, and the newest such minute is listed under the bars. 2. **Live** means the map shows now. Drag along the bars to replay a minute: the map shows which devices reported then, and **Back to live** returns. Devices whose data is not stored in the Proxus historian (devices removed from **SYSTEM INTERNAL DB**) cannot be replayed; the replay shows them in their current state and says how many there are. ## What's next - [Find what stopped](https://proxus.io/docs/monitor/find-what-stopped) - [See what depends on an object](https://proxus.io/docs/organize/operational-graph) - [Health Checks](https://proxus.io/docs/organize/health-checks): what in the setup is broken, not only what is offline now. --- # Alerts > The Alerts list and the alarm page: statuses, levels and sources of an alarm, how repeats are counted, and what the page shows around the moment it fired. Source: https://proxus.io/docs/monitor/alerts An alarm is raised when a [rule](https://proxus.io/docs/automate/rules) matches its condition, or when a [pipeline](https://proxus.io/docs/automate/pipelines) raises one. **Monitor > Alerts** lists them. While alarms are open, the menu item shows how many, for example **Alerts (1)**. Alarms cannot be created, edited or deleted by hand. You change their status with the toolbar actions. ## The list *Screenshot: The Alerts list filtered to Open with one alarm from LYS_LINE1_PLC, and the Acknowledge, Resolve and Ignore actions above it* 1. **Acknowledge**, **Resolve** and **Ignore**: tick one or more alarms, then choose an action. An action is available only when it applies to the selected alarms. 2. The filter: **Open**, **Acknowledged**, **Resolved & ignored** or **All**. The list opens on **Open**. 3. An alarm. Select it to open the alarm page. | Column | Meaning | | --- | --- | | **Alarm** | The rule's name, or the name the pipeline gave the alarm. | | **Reason** | Why it fired, from the alarm's report. | | **Device** | The device it fired for. | | **Status** | Where the alarm is in its life (below). An open alarm shows **New** in this column. | | **Last Activity** | When it last matched. | | **Count** | How many times it matched while it was open. | More columns, such as the level and the owner, can be added from the column chooser. ## Status | Status | Meaning | How it gets there | | --- | --- | --- | | **Open** | Raised and not yet taken. | Raised by a rule or pipeline. | | **Acknowledged** | Someone took it and follows it up. | **Acknowledge**. Only an open alarm can be acknowledged. | | **Resolved** | Closed, with a note on how it was fixed. | **Resolve** asks **How was it fixed?** and needs an answer. A pipeline alarm is also resolved by itself when the pipeline clears it, and a rule alarm when the rule [closes it](https://proxus.io/docs/automate/rules#close-the-alarm). | | **Ignored** | Closed without action. | **Ignore**, after a confirmation. | **Resolve** and **Ignore** work on open and acknowledged alarms. A resolved or ignored alarm cannot be reopened. Every change is recorded with who made it and when; **Audit Trail** on the alarm page lists the changes. ## Level and source The level is shown as a badge: **CRIT**, **WARN** or **NOTE**. A pipeline sets the level of the alarms it raises. Rule alarms are shown as warnings. The source is a **Rule** or a **Pipeline**. A pipeline alarm also records which step of the pipeline raised it and the alarm key, and has an **Open Pipeline** action that opens the pipeline. ## Repeats An alarm that matches again is not listed again. Its **Count** goes up and **Last Activity** moves on. - A **rule** alarm keeps counting while it is open or acknowledged, for the same device: taking an alarm whose condition goes on does not raise a second one. The same rule matching on another device raises a separate alarm for that device. Once it is resolved (by itself or by a person) or ignored, the next match raises a new alarm. - A **pipeline** alarm keeps counting while it is open or acknowledged, for the same device and alarm key. While its condition holds, the edge gateway repeats it at most once a minute, so **Count** goes up once a minute rather than on every reading. Once it is resolved or ignored, the next match raises a new alarm. ## The alarm page *Screenshot: An open alarm page with the WARN badge, the What happened section with the device and condition, and a timeline waiting for acknowledgement* 1. The status actions, as in the list, and **Audit Trail**. 2. The header: level, title, status, alarm number, how long it has been open and the source. 3. **What happened**: the reasons from the report, then **Device**, **Rule** or pipeline step, **Condition**, **Raised** and **Last seen**. 4. **Timeline**: raised, matched again, acknowledged and closed, each with who and when. While nobody has taken the alarm, it says **Waiting for someone to acknowledge**. Below these, **Solution** holds the note given when the alarm was resolved, and **Full report** the text the rule or pipeline wrote. The reasons and the full report are shown in your interface language, with long decimals rounded; notification channels receive the report as the Edge Gateway wrote it, in English. ### Around the alarm *Screenshot: The Around the alarm section with a temperature chart over 30 minutes, the alarm marked, and three cards below* 1. The window: **±15 min**, **±1 h** or **±4 h** around the moment the alarm fired. 2. The chart of the tag the alarm names, with the device's state band and the alarms and changes in the window. Only tags named in the alarm's report are used; when it names none, the device's state tag is shown. 3. Three cards: **When it fired** (the tag's value and the machine state at that moment), **Changed before** (the last platform change in the 24 hours before the alarm, and who made it) and **Last 7 days** (how often this alarm fired on this device). 4. **Open in workspace** opens the same tag and window in the [Trend Workspace](https://proxus.io/docs/monitor/trend-workspace). ## What's next - [Acknowledge and resolve an alert](https://proxus.io/docs/monitor/acknowledge-an-alert) - [Rules](https://proxus.io/docs/automate/rules): what raises an alarm. - [Rule actions](https://proxus.io/docs/automate/rule-actions): send a message when an alarm is raised. --- # Copilot > Ask about your plant in plain language and approve the changes Copilot prepares. What it reads, what it can change and how conversations are kept. Source: https://proxus.io/docs/monitor/copilot **Copilot** is an assistant built into the hub. You ask a question in your own words, for example "Which devices are not communicating, and why?", and Copilot answers from the plant data that you are allowed to read. It is in **Monitor > Copilot**, and on every screen as a side panel. Copilot needs an AI service before it can answer. An administrator adds one in **Platform > Copilot Settings**. See [Set up Copilot](https://proxus.io/docs/administer/copilot-settings). ## Where to open it | Place | How | | --- | --- | | **Monitor > Copilot** | The full page: your conversations on the left, the open one on the right. | | Side panel | The Copilot button, first of the icons at the top right, or **Ctrl+K** (**Cmd+K** on a Mac). **Esc** closes it. | | **Ask Copilot** on a record | On a record's toolbar, next to Save (in the **…** menu on a narrow screen): **Is something wrong?**, **What does it depend on, and what does it affect?**, **What changed in the last 7 days?** and **What is this screen for?** Choosing one opens the side panel and asks it about that record. | The side panel knows the screen you are on. When you open it on a record, for example a device's page, "this device" in your question means that device. *Screenshot: The Copilot side panel on the device KMP-01: the question, the sources Device details and Device diagnosis, a three-point answer and the AI service list* 1. Your question. 2. The sources Copilot read for this answer. 3. The answer, with the AI service, the model and the time under it. 4. The AI service that answers. You can change it between questions. ## What Copilot reads Copilot answers from the hub, not from memory. For each question it reads what it needs, and the answer shows a label for every source it used. | Source | What it gives Copilot | | --- | --- | | **Plant overview** | The plant at a glance: devices communicating and not, edge gateways, open alarms by level, configuration findings, and how many rules, pipelines, functions, targets, dashboards, reports and deliveries there are. | | **Plant tree** | Enterprise, site and area, with how many devices each has and how many are communicating. | | **Devices** | Every device you can see: location, edge gateway, profile, and whether it is communicating. Devices with problems come first. | | **Device details** | One device: its state, its latest tag values with quality and time, and its open alarms. | | **Edge gateways** | Whether each gateway is connected, when it was last seen and how many devices it runs. | | **Open alarms** | New and acknowledged alarms with level, device, rule and how often each occurred. Critical first. | | **Alarm history** | Open and closed alarms of a period (up to 90 days): who acknowledged and resolved each, the note on how it was fixed, or that the rule closed it on its own. | | **Device tags** and **Tag history** | The tags a device reported, and how they moved over a time range: lowest, highest, average and last value, and the curve, as in the [Trend Workspace](https://proxus.io/docs/monitor/trend-workspace). | | **Record types**, **Find records** and **Record values** | Any record of any screen you can open: profiles, rules, pipelines, functions, templates, dashboards, reports, deliveries, users, roles, certificates and settings. Long lists come in pages. | | **Dependencies** | How a device, gateway, rule, pipeline or target is wired: what it depends on and what uses its data, up to three steps away. | | **Audit Trail** | Who changed what and when, with the old and new value, from the [Audit Trail](https://proxus.io/docs/administer/audit-trail). Sign-ins and screen layouts are left out. | | **System logs** | The newest lines of the hub's and the edge gateways' logs, for roles that may open **System Logs**. | | **Health checks** | The [configuration health checks](https://proxus.io/docs/organize/health-checks): what breaks data flow, what drifted, what is unused, why it matters and how to fix it. | | **Device diagnosis** | Why a device does or does not deliver data: each link from the device to the hub is checked (enabled, edge gateway, profile, connection to the machine, data arriving, tag quality, open alarms), and the first failing link is named as the likely cause, with the device's health findings, recent changes and log lines. | | **Search the docs** and **Docs page** | This documentation, in the language of the interface. It ships with the hub, so it works without internet access. Copilot answers "how do I" and "what is" questions from it and links to the page it used. | Copilot reads with your permissions. If your role cannot see a device, Copilot cannot see it either, and it says that something may be outside your permissions rather than that it does not exist. A role limited to part of the plant (see [Users and roles](https://proxus.io/docs/administer/users-and-roles)) limits Copilot the same way: its devices, alarms, history and records, and the logs of its own edge gateways only. Passwords, keys, tokens and other secrets are never read, nor are the license details, raw telemetry rows or the connection settings of profiles, channels and targets. ## Changes you approve Copilot can prepare changes, but it never makes one on its own. Ask in plain language, for example "Disable Pump 2" or "Resolve alarm 1204, we replaced the sensor". Copilot shows a proposal card under its answer: - what changes: each field with its value now and after the change (for a new record, its values); - what depends on the record, when you switch it off or delete it, the same list the change guard shows; - why it cannot be done, when your role does not allow it or a rule of the record is not met. *Screenshot: A proposal card to switch off the device KMP-01: the Active field before and after, the pipelines, target and rule that depend on it, and the Approve and apply and Reject buttons* 1. What changes: each field, now and after. 2. What depends on the record, when it is switched off or deleted. 3. Your decision. Select **Approve and apply** (for a delete: **Approve and delete**) to make the change, or **Reject**. Only the person who asked can decide, once. | Copilot can | Records | | --- | --- | | Acknowledge or resolve an alarm | Resolving needs a note on what was done. The alarm is taken or closed in your name. | | Create, change or delete a record | Any record of a screen you may edit: devices, profiles and their tags, edge gateways, alarm rules and actions, pipelines, functions, outbound targets, notification channels, dashboards, reports, scheduled deliveries, users, roles, UNS permissions, certificates and settings. | | Change several records at once | The same change on many records of one kind, for example "disable these 12 devices". One card, applied to all of them together or to none. | | Prepare a plan | Several related changes on one card, for example a device profile, then a device that uses it, then an alarm rule. Approved once, made together or not at all. Up to 50 changes. Adding a machine, building a pipeline, trusting a certificate and actions each have a card of their own and are not part of a plan. | | Try an alarm rule first | From your sentence ("alarm if the oven stays above 200 °C for 5 minutes") Copilot writes the condition, replays it over the last hours of stored data as the rule editor does, tells you how often it would have fired, and then proposes the rule. | Copilot never sets passwords, keys or other secrets, never changes an administrator, an administrator role or your own account, and never changes what the platform writes itself (deployments, statistics, logs). When you approve, the change is made again with your permissions and the record's own rules, exactly as if you had saved it on its screen. If the record changed after Copilot proposed, nothing is written and the card says so: ask again for a new proposal. The [Audit Trail](https://proxus.io/docs/administer/audit-trail) records the change under your name, with "Copilot" and the conversation number as its source. ### Add a machine Ask, for example, "There is an OPC UA server on my computer: add it as a device and read its simulation values". Copilot uses the device wizard's own buttons, on the edge gateway that will read the machine: 1. It finds the server (**Discover servers**, for OPC UA and MTConnect) or, for other protocols, tries the address (**Test the connection**). Discovery looks at the edge gateway's own machine and the address you give; ask it to search the whole network of the gateway when the server is elsewhere (slower). These only read and need no approval. 2. For OPC UA it opens the server's folders and shows the current values of the variables you asked for. 3. It proposes the device on one card: the edge gateway, the protocol, the connection parameters and the data points. **Approve and apply** saves it as the wizard's **Save and verify** does: the profile, then the device, switched on. The device starts reading at once, and **Undo** removes the device and its profile. One card takes up to 50 data points; ask for the rest afterwards. Data point names must start with a letter and use only letters, digits and `_` (for example `DischargePressure_raw`), because pipelines, functions and rules read a value by its name. Copilot keeps the unit or the scale in its answer. On a secure OPC UA endpoint (**Sign** or **Sign and Encrypt**), the gateway and the server must trust each other first. When the gateway does not trust the server yet, Copilot proposes to trust its certificate: the card shows the certificate and its SHA-1 fingerprint, and you confirm twice. This needs the **Ask, propose changes and run actions** level. The server must also trust the gateway's certificate in its own settings, and Copilot gives you that fingerprint. A trusted certificate lets that server talk to every edge gateway, and trusting cannot be undone from Copilot: to withdraw it, reject the certificate in the [Certificate Store](https://proxus.io/docs/administer/certificates). A server that needs a user name and password is added in the [device wizard](https://proxus.io/docs/connect/devices/opc-ua), because Copilot never handles passwords. Copilot offers this to roles with **Ask and propose changes** (or more) whose role may also create devices and device profiles. ### Build a pipeline Ask, for example, "On the mixer, divide HR01 by 10 and keep it as a new tag HR01_scaled". Copilot builds the pipeline the way the [pipeline builder](https://proxus.io/docs/automate/pipelines) does: it picks the goal and steps from the builder's own list, fills in When, For, Steps and Then, and lets the builder check it. It tells you what the builder's preview shows on each device's latest values, then proposes the pipeline on one card. Copilot designs the alarms as an engineer would: a noisy value gets a dead-band limit, and a condition that depends on a machine running gets a lasting time, so a start-up surge raises no alarm. To change a pipeline built this way, ask Copilot to change it: it reads the pipeline and proposes the new version on one card, each part shown before and after. The change goes to the draft and can be undone; the running revision stays until the pipeline is published again. **Approve and apply** saves it as a draft, with its story, so it opens in the builder as if you had built it there and you can change it. A draft does not run. Copilot then offers to publish it in Shadow, and only after that Active; each is a separate card, and Active asks you to confirm twice. **Undo** deletes a draft that was never published. A pipeline has up to 12 steps and results. Copilot offers this to roles with **Ask and propose changes** (or more) whose role may also create pipelines. Publishing is an action, so it needs **Ask, propose changes and run actions** and the capability of each publish button: **Try pipelines** for Shadow, **Write to devices** for Active (see [Actions](#actions)). ### Confirming twice Some changes ask you to confirm a second time, after **Approve and apply**. The card says why: - something is deleted (a delete cannot be undone); - a record is switched off and something depends on it (the card lists what); - five or more records change at once; - the change touches who may do what, or the whole platform (users, roles, UNS permissions, certificates, settings, brand settings, Copilot services and their allowed roles). ### Actions Roles with **Ask, propose changes and run actions** (see [Set up Copilot](https://proxus.io/docs/administer/copilot-settings)) can also have Copilot press buttons for them, on the same approval card. Each needs the button's [capability](https://proxus.io/docs/administer/users-and-roles#capabilities), exactly as on its screen: | Area | Actions | | --- | --- | | Pipelines | Validate, Publish Shadow, Publish Active, roll back to an earlier revision, disable | | Functions | Build, deploy, undeploy | | Alarms | Ignore (acknowledge and resolve are changes, above) | | Notifications and targets | Send a test message, check a target's connection | | Scheduled deliveries | Run now, pause or resume, retry or cancel a run | | Templates | Install, uninstall | | Edge gateways | Revoke a gateway's access | | Certificates | Renew, trust, reject, make the default | **Approve and run** presses the button with your permissions, and the card shows its result. An action cannot be undone. Actions that reach the plant or the gateways (Publish Active, roll back, deploy, undeploy, templates, revoke, certificates) ask you to confirm a second time. Buttons that need a file, a designer or a person's own decision (export, import, the gateway terminal, passwords, the license) are never pressed by Copilot. ### Undo An applied change that created or changed records has an **Undo** button on its card. Undo deletes what the change created and sets the fields it changed back to their earlier values, in one step, again with your permissions. If someone changed one of those fields after Copilot did, nothing is undone and the card says so. Deletes and alarm decisions cannot be undone; the card says this before you approve. ### Proposals expire A proposal nobody approved within 24 hours expires: the plant may have changed since. Its card shows **Expired**. Ask again for a new proposal. ## Insights The **Insights** tab next to **Chat** lists things that need a look, found by background checks without anyone asking. Everyone who may use Copilot sees the insights about what they can see: a role limited to one site sees the insights about its own devices and gateways. An insight that counts across the whole plant (open alarms without an owner) is shown to roles that see the whole plant. The checks are fixed rules: no AI service is used and no data leaves the hub until you select **Ask Copilot** on an insight. *Screenshot: The Insights tab with one Unusual value warning, its explanation, the suggested next step and the Ask Copilot, Snooze 1 day and Dismiss buttons* 1. The level and what was found. 2. The suggested next step. 3. When it was first and last seen, and what you can do with it. | Insight | When it appears | | --- | --- | | **Noisy alarm** | A rule raised its alarm 10 times or more in the last 24 hours. | | **Open alarms without an owner** | Open alarms nobody acknowledged: after 24 hours, or 4 hours for critical ones. | | **Unstable link** | An edge gateway lost its link to the hub 3 times or more in the last 24 hours. | | **Hub refuses a gateway** | The hub refused an edge gateway's connection in the last 24 hours. | | **Certificate expires** | A certificate expires within 30 days and will not renew by itself. A platform certificate that should renew itself appears when 7 days are left. | | **Frozen value** | A tag of a continuously varying signal has not moved for 6 hours. A tag resting at its most common value (a stopped flow at 0) is not reported. | | **Unusual value** | In the last hour, a tag averaged far outside what it did in the past week. Counters and ramps are not reported. | | **Copilot budget** | An AI service used 80 percent of its monthly budget (see [Prices and budget](https://proxus.io/docs/administer/copilot-settings#prices-and-budget)). Shown to roles that may read **Copilot Settings**. | Each insight is a **warning**, or **critical** when it is urgent: a rule raised its alarm 50 times or more in a day, one of the unowned alarms is critical, a gateway lost its link 10 times or more, a certificate has 7 days or less, or a service spent its whole budget. A notification channel can send only the critical ones (see below). At most 15 frozen and 15 unusual values are listed at a time, the most telling first. Alarms, gateway links and certificates are checked every 15 minutes, tag values every hour; the first check runs 3 minutes after the hub starts. **Check now** runs the checks at once. An insight closes by itself when its condition is gone, and closed insights are removed after 30 days. Each insight says why it appeared and suggests a next step: - **Ask Copilot** starts a conversation about it. Copilot looks at the record and can prepare a change for you to approve. - **Snooze 1 day** hides it until tomorrow. It comes back if the condition is still there. - **Dismiss** hides it for as long as the condition lasts. Snoozing and dismissing hide the insight for everyone, so only administrators have these buttons and **Check now**. When insights are waiting, the Copilot button at the top right shows a dot, and its tooltip gives the count. ## Copilot going first - **Guided setup**: ask to connect a first machine, create a first alarm rule or a first dashboard. Copilot checks where you stand (is an edge gateway connected, is there a profile, does data arrive…), names the next step with its screen and docs page, and prepares the records for you to approve. - **Shift and week**: "How was the night shift?" gives the last 8 hours (or the last week): silent devices, disconnected gateways, alarms against the period before, the noisiest rules and devices. The same summary can be e-mailed on a schedule: see [Scheduled deliveries](https://proxus.io/docs/analyze/scheduled-delivery#copilot-summaries-instead-of-a-report). - **Recurring problems**: "What keeps going wrong?" finds the same alarm returning on the same device, edge gateways whose link keeps dropping, and insights that reopen, and suggests a lasting fix (for example a wait before the alarm, tried on past data first) instead of acknowledging the same alarm every day. - **Insights to a channel**: new insights can be sent to an e-mail, Teams or other channel: see [Notification channels](https://proxus.io/docs/connect/notification-channels#copilot-insights-through-a-channel). ## What it does not do It does not open dashboards or run reports, and it does not query the telemetry database with SQL. It reads up to 90 days back; for longer periods, use the [Trend Workspace](https://proxus.io/docs/monitor/trend-workspace). > **Warning:** Copilot can be wrong. Check an important answer on the screen it names, and read a proposal before you approve it. ## Conversations - **New conversation** starts an empty one. The first question becomes its title. - Select a conversation to continue it. Copilot remembers the questions and answers in it, up to the last 40 messages; start a new conversation for a new subject. It reads the plant data again for every question, so answers use current values. - The list at the top of the conversation chooses the AI service that answers, from the services the administrator enabled. You can change it between questions. - **Delete conversation** removes it after you confirm. - **Stop** ends an answer that is still being written. Conversations are stored in the hub until someone deletes them. Only you can continue or delete yours. Administrators can read every conversation with **Show everyone's conversations**, but cannot write in someone else's. Copilot shows this note next to the conversations. What is stored: your questions, the answers, the name of each source Copilot used, each proposal with your decision, and any error. The data Copilot read is not stored. ## Limits Copilot keeps what it reads short, so that answers stay fast and cheap: | What | Limit | | --- | --- | | Reads for one answer | 16. A question that needs more gets the answer so far; ask a narrower one. | | Devices in one list | 100, those with problems first. | | Alarms, Audit Trail entries, records in one page | 50 each. | | Tag history | 5 tags and 200 points per curve in one read, up to 90 days back. | | Log lines | The newest 100. | | Dependencies | 3 steps away. | | Conversation memory | The last 40 messages. | | Changes on one card | 50. A device takes 50 data points, a pipeline 12 steps and results. | | Proposal lifetime | 24 hours. | ## Language and time Copilot answers in the language of the hub's interface unless you write in another language. Times are shown in your browser's time zone. ## When there is no answer | Message | What to do | | --- | --- | | **Copilot is not set up yet** | No AI service is enabled. An administrator adds one in **Platform > Copilot Settings**. | | Your roles do not allow the Copilot | An administrator sets **Copilot Access** on one of your roles in **Security > Roles**. | | You have used today's Copilot limit | Your roles' **Copilot Daily Token Limit** is spent. It resets at midnight (UTC), or an administrator raises it. | | The monthly budget of a service is spent | Choose another service, or an administrator raises the **Monthly Budget**. | | The AI service is not set up completely | A field of the service is missing, for example its endpoint or region. An administrator completes it and selects **Test Connection**. | | The service rejected the API key | An administrator enters a new key for the service. | | The service is busy or the usage limit was reached | Try again in a minute, or choose another service. | | The service cannot be reached from the hub | The hub has no internet access, or the Ollama address is wrong. | | The AI service stopped before writing an answer | Ask again, or ask a narrower question. | | **Stopped.** | You selected **Stop**. | | The answer failed | The message gives the service's reason. | The error stays in the conversation, so you can see later why a question had no answer. ## Safety Device names, alarm texts and other plant data were typed by people or sent by machines. Copilot treats them as data and does not follow instructions written inside them. Answers are shown without HTML, and only web links (`http` and `https`) stay clickable. ## What's next - [Copilot settings](https://proxus.io/docs/administer/copilot-settings): add the AI service Copilot answers with, and set its limits. - [MCP server](https://proxus.io/docs/develop/mcp): let your own AI agents read the plant model with the same permissions. --- # Find what stopped > Go from a warning in the Operations Center to the device that stopped sending data, where it is, which gateway reads it and its last error. Source: https://proxus.io/docs/monitor/find-what-stopped At the end of this guide you know which device stopped sending data, where it sits in the plant and what its last error was, so you can tell the right person what to fix. ## Before you start - A user role that can open the **Monitor** screens and read the devices. - The [Operations Center](https://proxus.io/docs/monitor/operations-center) shows an item such as **1 device is not sending data**, or **Gateway … is silent**. ## Check which devices stopped 1. Open **Monitor > Operations Center**. 2. In **Needs attention**, find the item about devices or a gateway. 3. Select **Check** on a devices item (or **Probe** on a gateway item). *Screenshot: The Needs attention item 1 device is not sending data after Check, listing MFB_LYS_MIXER_7 with a timeout as its last error* 1. The item says how many of the devices send no data, and names up to three of them. 2. **Check** asks the hub which devices have no active stream. It does not restart anything. 3. The result lists each device with its state and last error, here a timeout: the gateway cannot reach the device's address. 4. **Devices** opens the device list. If the item is **Gateway … is silent**, the devices are probably fine: the gateway itself stopped reporting. **Probe** sends a test message to each silent gateway and lists which ones answered. A gateway that does not answer is not running or cannot reach the hub. See [Manage gateways](https://proxus.io/docs/connect/edge-gateways/manage-gateways). ## Find the device on the map 4. Open **Monitor > Topology**. 5. Type the device name in **Jump to a site, line or device** and choose it from the results. *Screenshot: Topology zoomed into the Dough line with MFB_LYS_MIXER_7 selected and its timeout error, place, gateway and protocol in the inspector* 1. The breadcrumbs show where the device is: site, area and line. 2. The inspector shows the device's state (**No data**), its last message, **Where**, **Gateway**, **Protocol**, **Data** and **Targets**. 3. **Open device** opens the device page with its live values, history and logs. Look at the other devices on the same line or behind the same gateway. If they are all grey, the cause is shared (the gateway, a switch, the network). If only one is grey, the cause is that machine or its connection settings. ## What's next - [The device page](https://proxus.io/docs/connect/devices/device-page): connection status, logs and history of one device. - [Troubleshoot devices](https://proxus.io/docs/troubleshoot/devices): cannot connect, wrong values, bad quality. - [Health Checks](https://proxus.io/docs/organize/health-checks): which rules and targets get nothing because of it. --- # Compare tags over time > Put tags of several machines on one chart in the Trend Workspace, compare them with yesterday, and save the view so you or others can open it again. Source: https://proxus.io/docs/monitor/compare-tags At the end of this guide you have the speed of two fillers on one time axis, compared with the same time yesterday, saved as a view your colleagues can open. ## Before you start - The devices store their data in the Proxus historian. A tag is listed only when it has data in the last 7 days. - A user role that may read the devices. ## Choose the tags 1. Open **Monitor > Trend Workspace**. 2. Type part of a device or area name in **Search devices or plant areas**, for example `FILLER`. 3. Select a device to list its tags, and tick the tags to chart. 4. Do the same for the next device. *Screenshot: The Devices panel with FILLER typed in the search box, MFB_RTM_L1_FILLER opened and its Speed tag ticked* 1. The search box. 2. The device, with the number of its tags on the chart. 3. A ticked tag. Its colour is the colour of its line. Each tag gets its own pane on the same time axis. Up to 8 tags fit on the chart. ## Choose the time and compare 5. Choose a range: **15 min**, **1 h**, **8 h**, **24 h** or **7 days**. Use **‹** and **›** to step to earlier or later ranges, and **Now** to come back. 6. In **Compare**, choose **Same time yesterday** (or **Previous period**, or **Same time last week**). *Screenshot: Two speed panes with yesterday's values as dashed grey lines and a Same time yesterday column in the table showing the change in percent* 1. **Compare** set to **Same time yesterday**. 2. The table's new column: yesterday's average and the change in percent. In the chart, yesterday is the dashed grey line. Point at the chart to read the values of all panes at the same moment. Scroll inside the chart to zoom in. ## Save the view 7. Select **Save view**. 8. Enter a **View name**. Tick **Share with everyone** if others should see it in their list. 9. Select **Save**. *Screenshot: The save form below the toolbar with the view name Filler speed, lines 1 and 2, Share with everyone ticked and the Save button* 1. **View name**. A view with the same name of yours is replaced. 2. **Share with everyone**. 3. **Save**. The view now appears in **Saved views…**. To send the view to someone without saving it, select **Copy link** and paste the address in a message. ## What's next - [Export a trend](https://proxus.io/docs/monitor/export-a-trend) - [Show machine state on a trend](https://proxus.io/docs/monitor/show-machine-state) - [Trend Workspace](https://proxus.io/docs/monitor/trend-workspace): every control of the screen. --- # Export a trend > Download the values shown in the Trend Workspace as a CSV or Excel file, and know what each file contains. Source: https://proxus.io/docs/monitor/export-a-trend At the end of this guide you have a file with the values of the tags on your chart, one row per moment and one column per tag. ## Before you start - Open the tags and the range you want in the [Trend Workspace](https://proxus.io/docs/monitor/trend-workspace). See [Compare tags over time](https://proxus.io/docs/monitor/compare-tags). - The export contains numeric tags only. Text and on/off tags are left out. ## Export 1. Wait until the chart has loaded. The export buttons are disabled while it loads. 2. If you need amounts as well as values (energy from power, volume from flow), tick **Show total over time**. 3. Next to **Export**, select **CSV** or **Excel**. The file is downloaded by your browser. *Screenshot: The figures table with Show total over time, the CSV and Excel export buttons and the Data column showing 1m avg plus min and max* 1. **Show total over time** adds the **Total** column. 2. **CSV** downloads a text file. 3. **Excel** downloads an `.xlsx` workbook. 4. **Data** shows how the values were drawn. The file holds the same points as the chart: over long ranges these are averages per time step, not every stored value. For raw values, choose a shorter range first. The file name holds the range, for example `trend-20261015-1338-20261015-2138.csv`. ## What is in the files - First column `time_utc` (ISO time in UTC), second `time_local` (in your browser's time zone), then one column per tag named `Tag · Device [unit]`. - One row per moment at which any tag has a value. A tag without a value at that moment has an empty cell. - Comma as separator and a dot as decimal sign, whatever your language, so other tools read it the same way. The file is UTF-8 and opens in Excel with device names intact. ```text time_utc,time_local,Speed · MFB_RTM_L1_FILLER [pcs/min],Speed · MFB_RTM_L2_FILLER [pcs/min] 2026-10-15T11:38:00.000Z,2026-10-15 13:38:00.000,392.4,231.7 ``` - Sheet **Data**: the local time (the time zone is in the header) and one column per tag. - Sheet **Summary**: **From**, **To** and **Time zone** of the range, then one row per tag with **Last**, **Min**, **Avg**, **Max**, **Total** and **Data**, as in the table on screen. ## What's next - [Reports](https://proxus.io/docs/analyze/reports): scheduled, formatted output of the same data. - [Telemetry API](https://proxus.io/docs/develop/telemetry-api): read stored values from your own program. --- # Show machine state on a trend > Set up a state band so trends show, behind the values, when a machine was running, waiting or stopped, with your own labels and colours. Source: https://proxus.io/docs/monitor/show-machine-state At the end of this guide, every trend of the device shows a coloured band with its state: for example green while it runs, amber while it is blocked and red while it is in fault. The same band appears on the alarm page and in presentation mode, which then also counts the stops. ## Before you start - The device has a tag that holds its state as a code, for example `State` with `1` for running and `4` for fault. Ask the PLC programmer what each code means. - The tag has values in the time range you look at: the form offers only the codes seen in that range. - A user role that may change the device. The band is saved on the device, so it is the same for every user. ## Set up the band 1. Open **Monitor > Trend Workspace**. 2. Find the device in the **Devices** panel and select it. 3. Under the device name, select **Set up a state band…**. 4. In **State tag**, choose the tag that holds the state. 5. For each value in **Values seen in this range**, enter a label and choose a colour. 6. Select **Save**. *Screenshot: The state band form for MFB_RTM_L1_FILLER with the State tag chosen and values 1, 3 and 4 labelled Running, Blocked and Fault* 1. **State tag**: the tag with the state code. 2. A value with its label and colour. Here `1` is **Running** with **Running / OK**, `3` is **Blocked** with **Warning** and `4` is **Fault** with **Stopped / fault**. 3. **Save**. The colours are **Running / OK**, **Warning**, **Stopped / fault**, **Information** and **Neutral**. Choose **Stopped / fault** only for states that mean the machine is stopped: presentation mode counts these as stops. The band now appears above the panes of the device's tags: *Screenshot: The trend of two filler speeds with a band above it showing Running periods in green and short blocked and fault periods* If the save fails with **The state band could not be saved**, your role may not change this device. ## Change or remove the band Select **State band: …** under the device name. Change the labels or colours and select **Save**, or choose **None** in **State tag** and save to remove the band. A value that the tag reports for the first time later is shown with its code until you give it a label. ## What's next - [Trend Workspace](https://proxus.io/docs/monitor/trend-workspace): presentation mode and the **Machine state** layer. - [Alerts](https://proxus.io/docs/monitor/alerts): the machine state when an alarm fired. --- # Acknowledge and resolve an alert > Take an open alarm so others know you are on it, look at what happened around it, then close it with a note on how it was fixed. Source: https://proxus.io/docs/monitor/acknowledge-an-alert At the end of this guide the alarm is closed as **Resolved**, with your name and a note on the fix, and it no longer appears in **Needs attention**. ## Before you start - An open alarm. It appears in the [Operations Center](https://proxus.io/docs/monitor/operations-center) under **Needs attention** and in **Monitor > Alerts**. - A user role that may change alarms. ## Take the alarm Acknowledge an alarm as soon as you start working on it. Others then see that it is in follow-up and who has it. 1. Open **Monitor > Operations Center**. 2. Find the alarm in **Needs attention**. *Screenshot: An open alarm in Needs attention with the WARN badge, the time since it was raised marked unacknowledged, and the Acknowledge and Open buttons* 1. The level: **CRIT**, **WARN** or **NOTE**. 2. How long it has waited. It turns red after 15 minutes without anyone taking it. 3. **Acknowledge** takes it from here. 4. **Open** opens the alarm page. 3. Select **Open** to read the alarm first, or **Acknowledge** to take it straight away. On the alarm page, **What happened** shows the reason, the device and the condition, and **Around the alarm** shows the tag's values and the machine state before and after the moment it fired. **Changed before** tells you whether someone changed a device, rule or gateway shortly before. See [Alerts](https://proxus.io/docs/monitor/alerts). 4. Select **Acknowledge** in the toolbar. *Screenshot: The alarm page after acknowledging: status Acknowledged in the header and Acknowledged by Admin in the timeline* 1. The status is now **Acknowledged**. 2. The timeline shows who acknowledged it and when. The alarm leaves **Needs attention** and is listed under **… acknowledged, in follow-up**. > **Note:** For an alarm raised by a rule, a new match after you acknowledged it raises a new alarm. For an alarm raised by a pipeline, new matches are counted on the acknowledged alarm until it is closed. ## Close the alarm When the cause is fixed: 5. On the alarm page, select **Resolve**. 6. In **How was it fixed?**, describe what you did. The field is required. 7. Select **Resolve**. *Screenshot: The Resolve alarm dialog with the fix described in How was it fixed? and the Resolve button* 1. **How was it fixed?** The text is kept with the alarm as **Solution**. 2. **Resolve** closes the alarm. If the alarm needs no action (a test, a known event), select **Ignore** instead and confirm. An ignored alarm is closed without a note. Neither a resolved nor an ignored alarm can be reopened. To handle several alarms at once, tick them in **Monitor > Alerts** and use the same actions from the toolbar. ## What's next - [Alerts](https://proxus.io/docs/monitor/alerts): statuses, levels and repeats. - [Rule actions](https://proxus.io/docs/automate/rule-actions): send an email or a message when an alarm is raised. --- # Connect > Bring machines, sensors and systems into Proxus, and send their data on to the places that use it. Source: https://proxus.io/docs/connect Everything Proxus knows about your plant arrives through **Connect**. Here you tell Proxus which machines to read, how to reach them, and where their data should go next. In the hub, these screens are in the **Connect** menu. ## What you set up here | Screen | What it is for | | --- | --- | | **Devices** | One entry per machine, PLC, robot or sensor that Proxus reads. A device belongs to one edge gateway and uses one device profile. | | **Device Profiles** | How to talk to a kind of device: the protocol, its connection settings and the list of tags to read. Many devices can share one profile. | | **Edge Gateways** | The Proxus runtime that sits close to the machines, reads them and forwards the data. The hub itself runs one gateway, called **SYSTEM**. | | **Outbound Targets** | Places outside Proxus that receive the data: databases, message brokers, cloud services, REST APIs. | | **Notification Channels** | Ways Proxus sends messages to people: email, SMS, Teams, Slack and others. | | **Import Devices** | Adds many devices at once from a spreadsheet. | | **Kepware Project Importer** | Brings devices and tags over from an existing Kepware project. | ## How the pieces fit A **device** is read by an **edge gateway**, using the protocol and tag list of its **device profile**. Every value the gateway reads is a **tag** value. The gateway publishes it in the Unified Namespace and sends it to the hub, which stores it in the Proxus historian. The gateway also sends it to each **outbound target** you chose for the device, so a target must be reachable from that gateway's network. ## Start here ## By protocol ## Gateways, profiles and destinations --- # Device profiles > A device profile holds the protocol, the connection settings and the tag list for one kind of machine. Many devices can share one profile. Source: https://proxus.io/docs/connect/device-profiles A **device profile** says how to talk to one kind of machine: the protocol, its connection settings and the list of tags to read. Each device uses one profile and adds what is its own, such as its address. Ten identical packing machines can share one profile, so a tag you add to the profile is read from all ten. The setup wizard creates a profile for you when you add a device with **A new profile**. Open **Connect > Device Profiles** to see all profiles, change them or share them between hubs. ## The list | Column | What it shows | | --- | --- | | **Profile** | The profile's name. | | **Protocol** | The protocol the gateway uses to read devices with this profile. | | **Tags** | How many tags the profile has. | | **Devices** | How many devices use the profile. | | **Description** | Your note about the profile. | The demo data includes sample profiles for many protocols. Copy one with **Clone...** as a starting point. ## The profile page *Screenshot: A profile page showing five devices that use it, ten tags, a 5 s polling interval and the tags by data type* 1. **Used by**, **Tags**, **Polling** (the time between reads of each device) and **Parameters** (the number of connection settings). 2. **Devices using this profile**, with the status, gateway and site of each. Changes to tags and connection parameters apply to every device in this list. 3. **Export to File** saves the profile, with its connection settings and tags, as a file for another hub. See [Share profiles between hubs](#share-profiles-between-hubs). Below the summary are the profile's fields: | Field | What it is | | --- | --- | | **Protocol** | The protocol. Required. | | **Profile Name** | A unique name. Required. | | **Description** | Optional. | ### Connection parameters and tags *Screenshot: The Tags tab of a profile with the Edit Tags and Import Tags buttons and a list of tags with their addresses and data types* 1. Two tabs: **Connection Parameters** and **Tags**. 2. **Edit Tags** opens the **Tag Editor**, where you add and change tags in a table. 3. **Import Tags** reads tags from pasted text or a CSV file in a PLC tag-table format. You pick the tags to add; a tag whose address is already on the profile is marked as a duplicate. 4. **Polling Interval** of a tag. `0` means the tag is read at the profile's polling interval. **Connection Parameters** is a list of **Key** and **Value** pairs: the address, the port and the protocol's own settings. The keys depend on the protocol. A value that is a password or a key is masked. The key `PollingInterval` is the time between reads, in milliseconds. > **Tip:** The setup wizard shows the same settings as labelled fields, with a help text under each and a connection test. To change the connection of one device, use [Configure with wizard](https://proxus.io/docs/connect/devices/configure-a-device) on the device rather than editing the profile. **Tags** has one row per value to read: | Column | What it is | | --- | --- | | **Name** | The tag name. It is the name the value has everywhere in Proxus: trends, rules, the Unified Namespace. | | **Address** | Where the value is in the device. Its form depends on the protocol, for example `x=3;0` for a Modbus holding register or `ns=2;s=Line1.Speed` for an OPC UA node. | | **Data Type** | Bool, Short, UShort, Int, UInt, Long, ULong, Float, Double, String, Bytes or DateTime. | | **Length** | The length in bytes, for String and Bytes. | | **Unit** | The engineering unit, such as `°C` or `rpm`. Pick one from the list or type your own. | | **Polling Interval** | How often this tag is read, in milliseconds. `0` uses the profile's interval. | For a [Simulator](https://proxus.io/docs/connect/devices/simulator) profile, each tag also has a **Generation Type**: how the simulated value moves. For an OPC UA profile, the **Tags** toolbar also has **Discover Servers** and **Browse Tags**, which open the OPC UA connection wizard. See [OPC UA](https://proxus.io/docs/connect/devices/opc-ua#the-opc-ua-wizard-on-a-profile). ## Change a profile that devices use When you save a profile that devices use, and the save changes its protocol, a connection parameter or a tag, Proxus first shows **Before you save this profile**. It lists: - how many devices get the change as soon as it is saved; - each change, for example a tag that is removed or renamed; - rules, pipelines and saved trend views that read a tag you remove or rename, by name. Tick the confirmation and select **Save the change**, or **Cancel**. > **Warning:** A renamed or removed tag stops getting new values under its old name. Its history stays, but a rule, pipeline or dashboard that reads the old name gets nothing. Check the list in the dialog before you save. ## Share profiles between hubs - **Export to File** (on the list, select the profiles first; or on a profile page) saves the profiles with their connection settings and tags as a JSON file. Passwords are left out. - **Import from File** (on the list) adds the profiles of such a file. Profiles that already exist are not changed. Tags without a name or an address, and repeated names, are left out; the message says how many. ## What's next - [Add a device](https://proxus.io/docs/connect/devices/add-a-device) with an existing profile: select it under **Start from**. - [Devices, profiles and tags](https://proxus.io/docs/concepts/devices-profiles-tags): how the pieces relate. - [Protocols](https://proxus.io/docs/reference/protocols): every protocol a gateway can read. --- # Outbound targets > Send device data to your own databases, message brokers, cloud services and REST APIs. Create a target, check it, and choose which devices deliver to it. Source: https://proxus.io/docs/connect/outbound-targets At the end of this guide, the data of the devices you choose also goes to a system outside Proxus, such as your own database or MQTT broker. The Proxus historian keeps it as well, as long as the device delivers to it (every new device does). An **outbound target** is one destination with its connection settings. The gateway that reads a device sends the device's data to each of its targets, so the hub's **SYSTEM** gateway sends for the devices it reads, and each edge gateway sends for its own devices. ## Before you start You need: - The connection details of the destination: host, port, user and password, database, topic or URL. - Network access from **every gateway that will send to it**. A database that only the plant network can reach needs devices on an edge gateway in that network. - For a TLS connection with a client certificate: the certificate and its private key files. - For a server whose certificate is self-signed or issued by your own CA: that CA certificate, so you can trust it in the [Certificate Store](https://proxus.io/docs/administer/certificates). - A user role that may create outbound targets. ## The target list Go to **Connect > Outbound Targets**. *Screenshot: The outbound target list with the In use filter, showing the system database target as Running for 76 devices* 1. **New** creates a target. 2. The filter shows **In use** targets by default: those that at least one device delivers to. Switch it to **All** to see every target, including the samples that come with Proxus. 3. **Status** shows whether the target delivers: green when it runs, red after a failure, grey while no device uses it. **Last Success**, **Last Failure** and **Last Error** say when it last worked and why it last failed. While a target keeps delivering, its last success is renewed about once a minute. When several gateways deliver to the target, each reports on its own and the target shows the worst: an error on one gateway is the target's error, while a gateway that stopped using the target does not hide another that runs it. Open the target to see each gateway's status, its last success and failure, and its queue. **SYSTEM INTERNAL DB** is the Proxus historian. It cannot be deleted or changed. New devices deliver to it by default: the setup wizard keeps it ticked. If you remove it from a device later (**Remove Target**, or the device's **Delivery** tab), that device's values are no longer stored and it has no history. ## Step 1: Create the target The quickest start is a sample: switch the filter to **All**, open the sample of the type you need (for example **MQTT**, **PostgreSQL** or **Kafka**), and select **Clone...**. The copy has every parameter of that type already listed. *Screenshot: The MQTT sample target with its target type, transport strategy and the list of parameters such as BrokerHost and BrokerPort* 1. **Target Type**: the kind of destination. See [Target types](#target-types). 2. **Transport Strategy**: what is sent. - **Pass Through**: every value read. - **On Change**: only values that changed since the last read. - **Pipelines Only**: nothing from normal device delivery. Only pipelines that name this target send to it. 3. **Parameters**: the connection settings as **Key** and **Value** pairs, such as `BrokerHost`, `BrokerPort` and `Topic` for MQTT. Passwords and keys are masked. 4. **Check** tests the settings. See step 2. Enter a **Profile Name** (unique) and an optional **Description**, fill in the parameters, then select **Save**. For **MQTT**, **AWS IoT Core**, **Azure IoT**, **SparkplugB** and **Azure Data Lake Gen2**, **Edit Parameters** above the parameter list opens a form with labelled fields instead of keys. For a TLS connection, select **Certificates** to upload the client certificate (PEM), its private key and, if needed, the CA certificate, all at once: the certificate that matches the key is the client certificate, whatever the files are called. ## TLS and server certificates Every TLS connection verifies the server. The server's certificate must match the address you entered, and it must chain to a trusted root: the target's **Trusted Server Certificate** from the Certificate Store, or the operating system's trusted roots. A target never accepts an unknown certificate, and **Test Connection** uses the same certificates and the same verification as real deliveries. - **MQTT**, **AWS IoT Core** and **SparkplugB**: choose **Trusted Server Certificate** in the parameter form. You can pick any CA or server certificate in the store, the Proxus Platform CA included. The old MQTT field for a CA file path is gone. - **Other types**: set the TLS keys in the parameter list. They are listed per type in the [Outbound targets reference](https://proxus.io/docs/reference/outbound-targets#tls-parameters). Certificate thumbprints are copied from the Certificate Store. - **Uploading with Certificates**: the client certificate and key go to the store, and the CA file you add is stored too and set as the target's trusted server certificate. For **AWS IoT Core**, Proxus downloads Amazon Root CA 1 and sets it; without internet access, the operating system's roots are used. [Secure connections to targets](https://proxus.io/docs/connect/secure-target-connections) walks through each type step by step, AWS IoT Core included. The gateway takes the certificates from the store at every send. When a certificate is renewed or replaced in the store, the targets use the new one without any change on the target. > **Warning:** Before 2.0.0, a target that connected to a server with a self-signed or private-CA certificate (for example your own MQTT broker, Splunk or an AWS IoT endpoint) worked because the certificate was not checked. Now the connection is refused. Upload the server's CA to the Certificate Store and choose it as the target's **Trusted Server Certificate**. ## Step 2: Check the target Select **Check**. *Screenshot: The Check window for the MQTT target with Run Probe On set to the hub, the runtime health and a configuration warning* 1. **Run Probe On**: where the test runs from: **Hub (this server)** or one of the edge gateways. Choose the gateway that will send the data, because a target that only the plant network can reach fails from the hub. 2. **Runtime Health**: the target's status and its last success, failure and error, from real deliveries. 3. **Configuration Check**: whether every parameter this target type reads is present and well formed. It lists **Errors** (the target cannot work), **Warnings** (worth a second look) and **Notes**. This check runs as soon as the window opens and does not contact the target. 4. **Test Connection** connects to the target from the place chosen in point 1. It sends no data. The **Connectivity** box shows the result: authenticated, reachable only, or failed, and how long it took. ## Step 3: Choose the devices A device delivers to a target when the target is in its list of outbound targets. Add it in one of these ways: - **For many devices at once**: in **Connect > Devices**, select the devices, then **Targets > Add Target**. Remove it the same way with **Remove Target**. - **For a new device**: in the setup wizard, step **Place and type**, tick the target under **Where does the data go?**. - **For one device**: on the device page, tab **Delivery**. The target's **Devices** count goes up, and its **Status** turns green after the first delivery. > **Note:** Pipelines and rules can also send to a target: the pipeline node **Target Output**, and the rule action **Trigger Outbound Target**. This is in addition to normal device delivery, so the same values may be sent twice. Use **Pipelines Only** on a target that should receive data from pipelines only. ## When a target is unreachable Data is not lost while a target is down, restarting or unreachable. The gateway first writes the data to its own durable queue and removes it only after the target has taken it. When the target is back, the waiting data is written in order. This also holds when the target is unreachable while the gateway starts. - **How long data waits**: the gateway's **Buffer Retention (hours)** (default 48 hours, up to 30 days). See [Manage gateways](https://proxus.io/docs/connect/edge-gateways/manage-gateways). - **Status**: while the target is unreachable, its error says how many queued messages are waiting at the gateway. - **Queued** on the target page: how many records wait in the gateways' queues for the target, updated at most every 15 seconds, and how many the target refused and the queue skipped. The gateway table shows both per gateway. - When no device on a gateway uses the target any more, that gateway stops sending to it. Its queued records are not counted under **Queued**: the page says how many the gateway keeps and until when (the gateway's buffer retention, 48 hours by default). They are sent if the target is used there again before then; after that they are removed. - **A record the target never accepts** (for example a value too long for a database column) is skipped after a few attempts and named in the status, so the data behind it does not wait. - **Duplicates**: rarely, a record that the target wrote but whose confirmation was lost is written twice. Nothing is lost. ## When a target fails - **Last Error** on the list and the target page shows the most recent error. - **Logs** on the target page shows the delivery entries of this target in the system log. - **Check** with **Test Connection**, run from the gateway that sends, tells a network problem from a sign-in problem. ## Target types These are the target types you can choose in **Target Type**. The parameters each one reads are listed in [Outbound targets reference](https://proxus.io/docs/reference/outbound-targets). | Group | Target types | | --- | --- | | Proxus | System Database (the built-in historian) | | Relational databases | Microsoft SQL Server, PostgreSQL Database, MySQL Database, Oracle Database, IBM DB2, SAP HANA, Firebird Database, SQLite Database, Microsoft Access, Adaptive Server Enterprise, SQL Anywhere, Advantage Database, Pervasive Database, VistaDB | | Time series and analytics | InfluxDB, TDengine, ClickHouse, Splunk | | Messaging | MQTT, SparkplugB, Kafka Messaging System, RabbitMQ Messaging System, Redis Database | | Cloud | AWS IoT Core, Azure IoT, Azure Data Lake Gen2 | | Other | REST API, XML File | ## What's next - [Outbound targets reference](https://proxus.io/docs/reference/outbound-targets): the parameters of each type. - [Pipelines](https://proxus.io/docs/automate/pipelines): transform data before it is sent. - [Troubleshoot data](https://proxus.io/docs/troubleshoot/data): data missing in a target. --- # Secure connections to targets > TLS setup for AWS IoT Core, MQTT, Sparkplug B, Kafka, RabbitMQ, Redis, ClickHouse, HTTP and SQL targets, using certificates from the Certificate Store. Source: https://proxus.io/docs/connect/secure-target-connections At the end of this guide, an outbound target sends its data over TLS: the target checks the server it connects to, and, where the server asks for it, proves who it is with a client certificate. You set this up once per target. The certificates live in the [Certificate Store](https://proxus.io/docs/administer/certificates), so renewing one there needs no change on the target. ## Before you start - The target exists. [Outbound targets](https://proxus.io/docs/connect/outbound-targets) shows how to create one. - You can open **Security > Certificate Store**. - You have the files your server's administrator or cloud service gave you: usually a CA certificate, and for a client certificate the certificate and its private key, in PEM format (`.pem`, `.crt`, `.key`) or as a `.pfx`. ## The two certificates of a target | Field | What it is | When you need it | | --- | --- | --- | | **Trusted Server Certificate** | The CA that signed the server's certificate. The target accepts the server only if its certificate chains to this CA and matches the address you entered. | When the server's certificate comes from your own or a private CA. Leave it empty for a server with a certificate from a public CA: the operating system's trusted roots are used. | | **Client Certificate** | The certificate and private key the target presents to the server. | When the server requires client certificates (mutual TLS), for example AWS IoT Core. | There are two ways to put the certificates in place: 1. **On the target page**: select **Certificates** and choose the client certificate, its private key and, if you have it, the CA certificate, all at once. Proxus finds out which file is which: the certificate that matches the private key becomes the client certificate, and another certificate among the files becomes the trusted server certificate. Both go into the Certificate Store and the target refers to them. 2. **In the Certificate Store**: select **Upload** and choose the files. A certificate without a key (a CA) is stored as a public certificate. Then pick the certificates on the target: - For **MQTT**, **AWS IoT Core** and **SparkplugB**, select **Edit Parameters** and choose them in **Client Certificate** and **Trusted Server Certificate**. - For the other types, add the parameter `ServerCertificateThumbprint` (and `CertificateThumbprint` for a client certificate) to the target. The value is the certificate's **Thumbprint**: open the certificate in the store to copy it. After any change, open the target, select **Check**, choose in **Run Probe On** the gateway that sends the data, and select **Test Connection**. It uses the same certificates and the same checks as real deliveries. ## AWS IoT Core AWS IoT Core always uses mutual TLS on port `8883`: the target needs the thing's device certificate and its key. ### In the AWS console 1. Open **AWS IoT Core > Manage > All devices > Things** and select **Create things**. Create a single thing, for example `proxus-line-1`. 2. In the certificate step, select **Auto-generate a new certificate**. 3. Attach a policy that lets the thing connect and publish. A minimal policy for a client ID equal to the thing name and the topic `proxus_device_data`: ```json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iot:Connect", "Resource": "arn:aws:iot:::client/proxus-line-1" }, { "Effect": "Allow", "Action": "iot:Publish", "Resource": "arn:aws:iot:::topic/proxus_device_data" } ] } ``` 4. Download the three files AWS offers: the device certificate (`…-certificate.pem.crt`), the private key (`…-private.pem.key`) and **Amazon Root CA 1** (`AmazonRootCA1.pem`). The private key can be downloaded only on this page. 5. Open **Settings** and copy the **Device data endpoint**, for example `a1b2c3d4e5-ats.iot.eu-central-1.amazonaws.com`. ### In Proxus 1. Open the AWS IoT Core target (clone the **AWS IoT Core** sample if you have none) and save it once. 2. Select **Certificates** and choose the three files together. The device certificate is stored with its key and becomes the **Client Certificate**; Amazon Root CA 1 becomes the **Trusted Server Certificate**. If you choose only the certificate and the key, Proxus downloads Amazon Root CA 1 itself. Without internet access from the hub, the operating system's trusted roots check AWS instead. 3. Select **Edit Parameters** and fill in: - **Endpoint**: the device data endpoint from step 5. - **Client Id**: the client ID the policy allows, here `proxus-line-1`. - **Port** `8883` and **Use TLS** on (both are the defaults). - **Topic**: a topic the policy allows. **Client Certificate** and **Trusted Server Certificate** are already filled in. 4. Save, select **Check**, choose the sending gateway in **Run Probe On** and select **Test Connection**. > **Note:** AWS IoT Core closes a connection without giving a reason when the policy does not allow the client ID or the topic, or when the certificate is inactive. If **Test Connection** connects and then drops, check the policy and that the certificate is **Active** in the AWS console. ## MQTT brokers (Mosquitto, EMQX, HiveMQ and others) 1. Find out the broker's TLS port (usually `8883`) and who signed its certificate. 2. If the broker's certificate comes from your own CA, upload the CA certificate to the Certificate Store. If it comes from a public CA, skip this step. 3. If the broker requires client certificates (`require_certificate true` in Mosquitto), get a client certificate and key from the broker's administrator and upload them with **Certificates** on the target. 4. On the target, select **Edit Parameters**: - **Broker Host**: the name in the broker's certificate. An IP address works only if the certificate contains it. - **Broker Port** `8883`, **Use TLS** on, **Tls Version** `Tls12` (or `Tls13` if the broker supports it). - **Trusted Server Certificate**: the CA from step 2, or empty for a public CA. - **Client Certificate**: the certificate from step 3, or empty. 5. Save and run **Test Connection**. To send to the MQTT broker of another Proxus gateway, choose **Proxus Platform CA** as the trusted server certificate: every gateway's broker certificate is issued by it. **SparkplugB** targets have the same fields and work the same way. ## Kafka Add these parameters to the target: | Parameter | Value | | --- | --- | | `BootstrapServers` | The brokers' TLS listeners, for example `kafka1:9093,kafka2:9093`. | | `SecurityProtocol` | `Ssl` for TLS, or `SaslSsl` for TLS with a user name and password (`SaslMechanism`, `SaslUsername`, `SaslPassword`). | | `ServerCertificateThumbprint` | The thumbprint of the cluster's CA in the Certificate Store. Leave it out for a public CA. | | `CertificateThumbprint` | The client certificate's thumbprint, if the cluster requires client certificates. | The broker's host name is checked against its certificate. ## RabbitMQ | Parameter | Value | | --- | --- | | `UseTls` | `true` | | `Port` | `5671` (the default when `UseTls` is `true`). | | `ServerCertificateThumbprint` | The server's CA, for a private CA. | | `CertificateThumbprint` | The client certificate, if RabbitMQ requires one (`ssl_options.fail_if_no_peer_cert`). | ## Redis | Parameter | Value | | --- | --- | | `UseTls` | `true` | | `Host` | The name in the server's certificate. | | `Port` | The server's TLS port. Many servers use `6380` for TLS; the default is `6379`. | | `ServerCertificateThumbprint`, `CertificateThumbprint` | As for RabbitMQ. | ## ClickHouse Set `UseTls` to `true`. The target then uses HTTPS on port `8443` unless you set `Port`. Add `ServerCertificateThumbprint` for a private CA and `CertificateThumbprint` if the server requires a client certificate. ## REST API, InfluxDB and Splunk A URL that starts with `https://` is TLS; the server's certificate is checked against it. Nothing else is needed for a server with a public CA certificate. For a private CA, add `ServerCertificateThumbprint`; for a client certificate, add `CertificateThumbprint`. For Splunk, enter the HTTP Event Collector address with `https://`, for example `https://splunk.example.com:8088`. The older `UseSSL` parameter has no effect. ## PostgreSQL and MySQL | Parameter | Value | | --- | --- | | `SslMode` | `VerifyFull` (recommended): encrypts and checks the server's certificate and name. `VerifyCA` checks the certificate but not the name. `Prefer` (PostgreSQL) and `Preferred` (MySQL) encrypt without checking the server. | | `ServerCertificateThumbprint` | The database server's CA, for `VerifyCA` and `VerifyFull`. | When `SslMode` is not set, the database driver's default applies, which encrypts when the server offers it but does not check the server. Client certificates are not supported for these two databases. ## Azure IoT Hub The connection always uses TLS on port `8883`. The hub is checked against the operating system's trusted roots, and the device signs in with its **SharedAccessKey**. No certificate is needed. X.509 device authentication is not supported in this version. ## Targets that do not use the Certificate Store | Type | TLS | | --- | --- | | **TDengine** | `UseTls` turns TLS on; the server is checked against the operating system's trusted roots. | | **SQL Server** | `Encrypt` turns TLS on. `TrustServerCertificate` skips the server check: use it only for tests. | | **Azure Data Lake Gen2** | Always HTTPS, checked against the operating system's trusted roots. | ## When the connection fails | What you see | Cause | What to do | | --- | --- | --- | | **Test Connection** says the certificate does not match the host. | The address on the target is not a name in the server's certificate. | Enter the name the certificate was issued for, or ask for a certificate that includes your address. | | **Test Connection** says the certificate is not trusted. | The server's CA is not the trusted server certificate and is not a public CA. | Upload the CA to the Certificate Store and choose it as **Trusted Server Certificate**. | | **Certificates** says the private key belongs to none of the chosen certificates. | The key and the certificate are from different pairs. | Choose the certificate that was issued with this key. | | AWS IoT Core connects and drops at once. | The policy does not allow the client ID or topic, or the certificate is inactive. | See the note in [AWS IoT Core](#aws-iot-core). | | The test works from the hub but not from the gateway. | The gateway's network cannot reach the server, or reaches it under another name. | Run the test from the gateway that sends, and check its firewall and DNS. | ## What's next - [Outbound targets](https://proxus.io/docs/connect/outbound-targets): transport strategy, checking a target, choosing devices. - [Certificate Store](https://proxus.io/docs/administer/certificates): renewing, replacing and removing certificates. - [Outbound targets reference](https://proxus.io/docs/reference/outbound-targets): every parameter of every target type. --- # Notification channels > Set up the email, SMS, Teams, Slack and other channels that rules and pipelines use to send messages to people, and send a test message. Source: https://proxus.io/docs/connect/notification-channels At the end of this guide, Proxus can send messages through your email server, SMS provider or chat tool, and you have checked it with a real test message. A **notification channel** is one way of reaching people, with its settings. Rules, pipelines and scheduled deliveries then send through it. ## Before you start You need: - The account details of the service: for example the SMTP server, user and password for email, or the incoming webhook URL for Slack, Teams or Discord. - Outbound network access from the hub to that service. - A user role that may create notification channels. ## The channel list Go to **Connect > Notification Channels**. *Screenshot: The notification channel list with sample channels for Discord, Email, Teams, Slack, SMS and others, all marked Sample values* 1. **New** creates a channel. 2. **Status** says whether the channel is ready: - **Configured**: every required parameter is filled in. - **Sample values**: the parameters still hold the placeholder values of a sample. - **Missing: …**: the named parameters are empty. - **Delivery failing**: the parameters are filled in, but the last notification sent through the channel failed after the last one that went out. 3. **Actions**: how many rule actions send through the channel. 4. **Last Success** and **Last Failure**: when a notification last went out through the channel, and when one last failed. Open the channel to read **Last Error**, the reason the provider gave. Proxus comes with one sample channel per type. They hold placeholder values and do not work until you replace them. ## Step 1: Create the channel 1. Select **New**, or open the sample of the type you need and select **Clone...**. The sample has every parameter of its type already listed. 2. Choose the **Notification Type**. 3. Enter a **Name** (unique), for example `Ops Slack #alerts`, and a **Description**. 4. Under **Parameters**, fill in a **Key** and **Value** for each setting. Values of passwords and tokens are masked. 5. Select **Save**. The keys each type reads (required ones in bold): | Notification Type | Parameters | | --- | --- | | **Email Notification** | **SmtpServer**, SmtpPort (587 if empty), **Username**, **Password**, **From**, **To**, Cc, Bcc, UseSsl | | **SMS Notification** | **AccountSid**, **AuthToken**, **From**, **To** (a Twilio account) | | **WhatsApp Notification** | **AccountSid**, **AuthToken**, **From**, **To** (a Twilio account) | | **Push Notification** | **Token**, and the Firebase Cloud Messaging settings: FCM_V1, ProjectId, AccessToken, ServerKey | | **Slack Message** | **WebhookUrl**, BlocksJson | | **Microsoft Teams Message** | **WebhookUrl** | | **Discord Message** | **WebhookUrl** | | **Telegram Message** | **BotToken**, **ChatId**, ParseMode | | **Line Message** | **AccessToken**, **UserId** | | **Facebook Messenger Message** | **AccessToken**, **RecipientId** | > **Note:** **Pusher Notification** is listed as a type but cannot send in this version. A test on such a channel says so. ## Step 2: Send a test message On the channel's page, select **Test**. *Screenshot: The Test window for the Slack channel with an empty Send To field, a passed configuration check and the Send Test button* 1. **Send To (override)**: send the test to another recipient than the channel's own, for example your own email address. Leave it empty to use the channel's recipient. This works for email, SMS, WhatsApp, Telegram, Line, Messenger and push channels. 2. **Configuration Check**: whether every required parameter is present. Missing or invalid ones are listed. 3. **Send Test** sends a real message, with the **Title** and **Body** shown. You can change both. The **Result** box shows **Sent successfully. The provider accepted the message.**, how long it took and the provider's reference. Acceptance by the provider does not prove that the message reached the inbox or the app: check that it arrived. If it fails, the result says why, for example **Not sent: channel parameters are incomplete.** or **Not sent: the attempt timed out.** Tests are limited to one every 15 seconds. > **Warning:** **Send Test** sends a real message to real people. Use **Send To (override)** to send it to yourself when the channel's recipient is a team. ## Step 3: Use the channel - **Rules**: a rule action of type **Notification Action** sends through the channel you choose in **Notification Channel**. See [Rule actions](https://proxus.io/docs/automate/rule-actions). - **Pipelines**: the **Notification** node sends through a channel. See [Pipelines](https://proxus.io/docs/automate/pipelines). - **Scheduled reports**: a scheduled delivery can send its report through an email channel. See [Scheduled delivery](https://proxus.io/docs/analyze/scheduled-delivery). When messages do not arrive, select **Logs** on the channel's page: it shows the system log entries of sends through channels of this type. ## Copilot insights through a channel **Copilot Insights** on a channel sends it the new [Copilot insights](https://proxus.io/docs/monitor/copilot#insights): **Do not send** (the default), **Critical only** or **Warning and critical**. Each insight is sent once, when it opens, with what was found and the suggested next step, in the hub's language. The checks are fixed rules: no AI service is used. Turning the option on does not send the insights that were already open. ## What's next - [Notification channels reference](https://proxus.io/docs/reference/notification-channels) - [Rule actions](https://proxus.io/docs/automate/rule-actions) --- # Add a device > Connect one machine with the setup wizard. Pick the protocol, test the connection, add tags, place the device and watch its first values arrive. Source: https://proxus.io/docs/connect/devices/add-a-device At the end of this guide, a new device is running in Proxus and you can see its live values. The setup wizard takes you through five steps. Nothing is saved until the last one, so you can go back and change anything on the way. ## Before you start You need: - An **edge gateway** that can reach the machine on the network. The hub's own gateway, **SYSTEM**, works for machines on the hub's network. A gateway shows **Connected** when it is online. - The machine's **address** (IP address or host name) and, if it is not the protocol's usual one, its **port**. - The **list of values** you want to read and where they are in the machine (register numbers, PLC tag names, OPC UA nodes). A spreadsheet or the PLC's tag table is ideal: you can paste it. - A user role that may create devices. > **Tip:** Have the PLC programmer's tag list open. The wizard reads a copy-paste from Excel or a TIA Portal tag table as it is, and turns Modbus datasheet numbers such as `40001` into the right address for you. ## Open the wizard Go to **Connect > Devices** and select **New** (1). *Screenshot: The device list with the New button marked in the toolbar* The wizard opens in its own tab. If you left a wizard unfinished earlier, it asks whether to **Carry on** with that draft or **Start over**. ## Step 1: Protocol and gateway *Screenshot: The first wizard step with the SYSTEM gateway selected, modbus typed in the search box and the Modbus TCP card selected* 1. Choose the **gateway** that will read the device. The connection is tested from this gateway, so pick the one that is on the machine's network. 2. Find the **protocol**. The most common ones are shown first; type a protocol or a vendor name in the search box to see the rest ("modbus", "s7", "melsec", "fanuc"). 3. Select the protocol's card. Only protocols the gateway can run are listed. Then select **Next: Connection** at the bottom of the wizard. > **Note:** Under **Start from** you can pick an existing device profile instead of **A new profile**. The device then uses that profile's connection settings and tags, and the wizard only asks for what differs (the address and the name). Use it when you add another machine of a kind you already have. ## Step 2: Connection *Screenshot: The connection step with IP address 127.0.0.1 and port 5020 entered and a passed connection test on the right* 1. Enter the **IP address** of the machine, as the gateway sees it. 2. Enter the **Port**, or leave it empty to use the protocol's usual port (for example 502 for Modbus TCP, 102 for Siemens S7, 44818 for EtherNet/IP). 3. **Read every** sets how often all tags of this device are read. Leave **Profile default** unless you have a reason to read faster or slower. 4. Select **Test the connection**. The gateway itself tries to reach the machine, so a test that passes here also works in production. 5. The result shows each check: whether the gateway reached the address, and whether the machine accepted the protocol session. Protocol-specific settings (byte order, unit ID, rack and slot, security) are shown with the address, and less common ones under **Advanced**. Each field explains itself underneath. > **Warning:** The test is optional, but if you skip it, a wrong address or a firewall rule only shows up after the device is saved. If the test fails, the message says what to check: a network problem (the gateway cannot reach the address) is different from a protocol problem (the machine answered but refused the session). Select **Next: Tags**. ## Step 3: Tags A **tag** is one value you read from the machine: a speed, a temperature, a counter, a state. Add them in the way that suits you, using the tabs at the top of the step: | Tab | Use it when | | --- | --- | | **Table** | You type a few tags by hand. | | **Paste** | You have the tags in a spreadsheet or a PLC tag table. | | **From file** | You have a `.csv` or `.xlsx` file, such as a TIA Portal "PLC tags" export. | | **From another profile** | Another machine of the same kind already has its tags in Proxus. | | **From the device** | The protocol can list the device's values for you (OPC UA, SNMP, MTConnect, Allen-Bradley). | ### Paste tags from a spreadsheet *Screenshot: The Paste tab with five rows of tags pasted: name, register number, type and unit* 1. Select the **Paste** tab. 2. Paste one tag per line with the columns **name, address, type, unit**, separated by tabs (as Excel copies them), commas or semicolons. A header row is skipped. 3. Select **Add to the list**. For example: ```text Speed 40001 UShort rpm BatchCount 40004 UShort Temperature 40011 Float °C MotorCurrent 40013 Float A ``` For Modbus, a register number from a datasheet becomes the address the driver reads: `40001` becomes `x=3;0` (holding register 0), `30001` becomes `x=4;0` (input register 0), `10001` becomes `x=2;0` (discrete input) and `1` becomes `x=1;0` (coil). For Siemens, use **From file** with a TIA Portal "PLC tags" export: its addresses (such as `%MW10`) become the addresses the driver reads (`M10`), and the name, data type and address columns are found by their headers. ### Check the tags against the device *Screenshot: The tag table with five tags, their addresses, types and units, and a test-read value next to each* 1. Check the **table**: name, address, type and unit of each tag. Fix anything directly in the table. 2. Select **Read all once**. The gateway reads every tag one time and shows the value next to it. A wrong address shows its error on the row, here and not later on site. 3. The **Address helper** builds an address from its parts (a register number for Modbus; data block, offset and bit for Siemens) so it cannot be mistyped. Fill it in and select **Add to the list**. 4. **Profile name**: the connection and these tags are saved as a device profile under this name, so other devices of the same kind can use them later. > **Note:** A tag that cannot be read can still be saved. Its state shows on the device page, so you can fix the address later without losing the rest. Select **Next: Place and type**. ## Step 4: Place and type *Screenshot: The place and type step with the device name, site and area filled in and Filler / Packaging selected as the device type* 1. **Device name**: a unique name. Most plants use site, line and equipment, for example `LYS_PACKER_04`. If your administrator turned on a naming rule, the field tells you the expected pattern. 2. **Place**: where the device sits, from **Enterprise** down to **Equipment module**. All levels are optional. Select a field to pick a value already in use, or type a new one. Each list only offers values under what you chose above it. The place decides where the device appears in the Unified Namespace. 3. **Device type**: what the machine is. Proxus does not guess it; the type sets the device's icon and how the Operations Center shows it. Then select **Save and verify**. Further down the same step: - **Where does the data go?** The Proxus historian (**SYSTEM INTERNAL DB**) is ticked and cannot be unticked here, so the values of a new device are stored. Tick any outbound target that should also receive it (a database, a broker, a cloud service). You can change this later. - **Machine state** (optional): a tag that says whether the machine is running. Trend screens then show a state band behind the values. > **Warning:** If **Save and verify** does nothing, look at the box above the buttons: it lists what is still missing, and the fields that need attention are marked in red. A device name and a device type are always required. ## Step 5: Verify *Screenshot: The verify step showing four completed stages and the first values of each tag* The wizard saves the device and follows it live: 1. Four stages turn green in order: **Saved** (the change is written to the audit trail), **Sent** to the gateway, **Device connected**, and **First values**. 2. Each tag shows its first value and how long ago it arrived. 3. Select **Open the device** to see its page, or **Add another like this** to set up a similar machine with the same settings. You can leave this page at any time; the device keeps running. ## Change a device later Open the device and select **Configure with wizard**. The same five steps open with the device's current settings, every step can be visited directly, and saving updates the device instead of creating a new one. ## What's next - [The device page](https://proxus.io/docs/connect/devices/device-page): watch the device's status and live values. - [Device profiles](https://proxus.io/docs/connect/device-profiles): keep the shared settings of machines of one kind. - [Import devices](https://proxus.io/docs/connect/devices/import-devices): add many devices at once from a spreadsheet. - [Outbound targets](https://proxus.io/docs/connect/outbound-targets): send the device's data to your own systems. --- # Change a device > Change a device's connection, gateway, name or place with the setup wizard, test it before you save, or add another device like it. Source: https://proxus.io/docs/connect/devices/configure-a-device At the end of this guide, an existing device has its new settings (another address, another gateway, a new name or place) and you have seen it connect again. The setup wizard that added the device also changes it, so every change can be tested before it is saved. ## Before you start You need: - The device, already in **Connect > Devices**. - A user role that may change devices. ## Open the device in the wizard Open the device (select its row in **Connect > Devices**) and select **Configure with wizard**. In the device list, you can also select one device and then **Configure with wizard**. The wizard opens in a new tab named **Configure** and the device name, with the device's current settings. *Screenshot: The setup wizard opened for LYS_PACKER_04 with all five steps listed and the device's profile under Start from* 1. Every step shows what is set now: the address, the number of tags, the device name. Select any step to go to it directly. **Verify** opens only after you save. 2. **Start from** shows the device's profile: its connection and tags come with it. Nothing is saved until you select **Save and verify** in **Place and type**. **Cancel** leaves the device as it was. ## Change the connection Select **Connection**. *Screenshot: The connection step of an existing device with a note that the values come from the profile Case packer* 1. The note says which profile the values come from. **A value you change here applies to this device only**: the profile and the other devices that use it do not change. 2. Change the **IP address**, the **Port** or any other setting. 3. Select **Test the connection**. The test runs on the device's gateway, as for a new device. To move the device to another gateway, select **Protocol and gateway** and choose the gateway, then test the connection again: the new gateway must reach the device. ## Change the tags The tags of a device belong to its profile. In the **Tags** step, the table is read-only and shows the profile's tags; **Read all once** still reads each of them from the device. To change the tags: - **For every device of this kind**, change the profile in [Device Profiles](https://proxus.io/docs/connect/device-profiles). - **For this device only**, clear **Start from** in **Protocol and gateway** so it shows **A new profile**. The device then gets a new profile of its own, made from its connection and the tags you enter, and the other devices keep the old one. ## Change the name, the place or the type Select **Place and type**. Change the **Device name**, the **Place** or the **Device type**, and the outbound targets under **Where does the data go?**. A new name must be unique and follow your naming rule, if your administrator set one. > **Warning:** A device's name is part of its address in the Unified Namespace and is used in rules, pipelines and dashboards. After a rename, check what used the old name. On the device page, **Dependencies** (under **...**) lists it. ## Save and verify Select **Save and verify**. The device is updated in place (no new device is created), and the change is written to the audit trail. The **Verify** step then follows the device as it connects again and shows each tag's first value. > **Note:** Saving from the wizard makes the device active. If the device was inactive on purpose, clear **Active** under **Configuration** on its page again after you save. ## Add another device like this one For a second machine of the same kind, open the first device and select **Add one like this**. At the end of the setup, **Add another like this** in **Verify** does the same. *Screenshot: The wizard started from an existing device, on the connection step with an empty IP address field* 1. The wizard copies the protocol, the profile, the gateway, the place, the device type and the outbound targets of the first device. 2. It opens on **Connection** with an empty **IP address**. Enter the new machine's address and test it. Then enter the new device's name in **Place and type** and select **Save and verify**. The new device uses the same profile as the first one. ## What's next - [The device page](https://proxus.io/docs/connect/devices/device-page) - [Device profiles](https://proxus.io/docs/connect/device-profiles): change the tags of every device of a kind. - [Import devices](https://proxus.io/docs/connect/devices/import-devices): change many devices at once from a spreadsheet. --- # The device page > What the device page shows about one machine: its status, live values and trends, value history, delivery to targets, diagnostics and logs. Source: https://proxus.io/docs/connect/devices/device-page Every device has a page that shows whether it is connected and what it is reading. Open it from **Connect > Devices** by selecting the device's row, or from **Open the device** at the end of the setup wizard. The page has three parts, from top to bottom: a summary, a row of tabs, and a **Configuration** section that is closed until you open it. ## Summary *Screenshot: The top of a device page with the Connected status, the five figures, alarms and delivery, and the toolbar* 1. **Status**, next to the device's profile, gateway and type. Above the name is the device's place, from enterprise down to equipment module. Point at the status to see the gateway's full status text. 2. Five figures: - **Last value**: when the gateway last received a value from the device. - **Tags**: how many tags the device has, and whether all of them have good quality. - **Reads**: how many reads succeeded, and how many failed. - **Response**: the device's average response time. - **Alarms**: how many alarms are open for the device. 3. **Alarms** lists up to five open or acknowledged alarms of this device. **Delivery** lists the outbound targets that receive its data, each with its state and the time of its last success and last failure. 4. The toolbar. See [Actions](#actions) below. ### Status | Status | Meaning | | --- | --- | | **Connected** | The gateway reads the device and every tag. | | **Warning** | The device is connected, but some tags cannot be read. | | **Protocol Issue** | The device answers but reports a protocol error, a wrong address or data type, or does not answer in time. | | **Retrying** | The connection was lost and the gateway tries again shortly. | | **Error**, **Critical** | The gateway cannot connect: the address cannot be reached, the connection is refused, or sign-in failed. | | **Gateway Offline** | The gateway that reads the device is not connected to the hub. | | **Offline**, **Sleep Mode** | The device has stopped sending data. | | **Stopped**, **Disabled** | The device is not active, so the gateway does not read it. | | **Info**, **Unknown** | No status has been reported yet. | When a device is not connected, its logs usually say why. For the common causes, see [Troubleshoot devices](https://proxus.io/docs/troubleshoot/devices). ## Tabs ### Live values *Screenshot: The Live values tab with one row per tag: key, value, trend sparkline, quality and update time* 1. The tabs: **Live values**, **History**, **Delivery**, **Diagnostics** and **Hierarchy**. 2. One row per tag, updated as values arrive. Select a row to open its trend. 3. **Quality** is **Good**, **Uncertain** or **Bad**. Rows that are not good are highlighted. The columns are **Key** (the tag name), **Value**, **Trend** (a small chart of the recent values and the change, or **Text** for a text tag), **Quality** and **Updated**. Use the search box to find a tag, and **XLSX**, **XLS** or **CSV** to save the table as a file. ### Trend of one tag Selecting a row opens a panel with the tag's recent values. *Screenshot: The trend panel for the Speed tag with the 1 h range selected, a line chart and the last, average, minimum and maximum values* 1. The time range: **15 min**, **1 h**, **8 h** or **24 h**. 2. The chart. Drag the handles under the chart to look at part of the range. 3. **Last**, **Avg**, **Min** and **Max** for the range. 4. **Open in workspace** opens the same tag in the [Trend Workspace](https://proxus.io/docs/monitor/trend-workspace), where you can compare it with other tags. Under **In this range**, the panel lists stops, alarms and configuration changes that happened in the range. Stops are shown only for a device that has a machine state tag. Close the panel with the close button or the Escape key. ### History The values the device sent most recently, one row per value: **Time**, **Key**, **Type**, **Value** and **Quality**. This is the history of the values, not of changes to the device; for changes, use **Audit Trail**. ### Delivery The outbound targets that receive this device's data. To add or remove targets for many devices at once, use **Targets** in the device list. See [Outbound targets](https://proxus.io/docs/connect/outbound-targets). ### Diagnostics Counters kept by the gateway for this device, as **Key** and **Value**: last communication and last data time, successful and failed operations, average response time, connection errors, the number of values processed, and data quality figures. ### Hierarchy The device's place: **Enterprise**, **Site**, **Area**, **Process cell**, **Equipment module** and **Group**. The place decides where the device appears in the [Unified Namespace](https://proxus.io/docs/concepts/unified-namespace). ## Configuration Open **Configuration** at the bottom of the page to see the device's own fields: name, device type, device profile, gateway, **Active**, attributes and image. Clearing **Active** stops the gateway from reading the device; the change is saved at once. To change the connection or the place, [use the setup wizard](https://proxus.io/docs/connect/devices/configure-a-device) instead: it tests the connection before it saves. ## Actions | Action | What it does | | --- | --- | | **Configure with wizard** | Opens the setup wizard with this device's settings. See [Change a device](https://proxus.io/docs/connect/devices/configure-a-device). | | **Add one like this** | Starts a new device with the same profile, gateway and place. Only the name and the address are asked. | | **Audit Trail** | Who changed what on this device, and when. | | **Clone...** | Copies the device's record. | | **Delete** | Deletes the device. A device that is active cannot be deleted: clear **Active** first. | | **Dependencies** (under **...**) | Shows what uses this device's tags: rules, pipelines, dashboards and others. | | **Query** (under **...**) | Opens a query window for the device's stored values. | | **Logs** (under **...**) | Shows the system log entries for this device. Select an entry to read the whole message. | > **Tip:** When a device shows **Warning**, open **Logs** first. The entry names the tag or the check that failed. ## What's next - [Change a device](https://proxus.io/docs/connect/devices/configure-a-device) - [Troubleshoot devices](https://proxus.io/docs/troubleshoot/devices) - [Trend Workspace](https://proxus.io/docs/monitor/trend-workspace) --- # Import devices from a spreadsheet > Add or update many devices at once from a CSV or Excel file. A dry run shows every change before anything is saved. Source: https://proxus.io/docs/connect/devices/import-devices At the end of this guide, the devices listed in your spreadsheet exist in Proxus, or have been updated, and are running on their gateways. The import never saves anything before you have seen a dry run of every row. ## Before you start You need: - The **device profiles** the devices will use. The import does not create profiles, and it does not take tags: every device gets its protocol, connection settings and tags from its profile. Create a profile first with the [setup wizard](https://proxus.io/docs/connect/devices/add-a-device) or on [Device Profiles](https://proxus.io/docs/connect/device-profiles). - The **edge gateways** that will read the devices. The import does not create gateways either. - A user role that may create and change devices. ## Prepare the file The file is a CSV file or an Excel workbook (`.xlsx`) with one device per row and a header row. Only the first sheet of a workbook is read. A CSV file may use a comma, a semicolon or a tab between columns. The file can be up to 5 MB. The quickest start is a template: open **Connect > Import Devices** and select **Download Excel template** or **Download CSV template**. Each has the header row and one example device. | Column | Required | What to enter | | --- | --- | --- | | `DeviceName` | Always | The device name. It must appear only once in the file. A device that already has this name is updated. | | `Profile` | For a new device | The name of an existing device profile, as on **Device Profiles**. | | `Gateway` | For a new device | The name of an existing edge gateway, as on **Edge Gateways**. | | `Host` | No | The device's IP address or host name. Saved for the device only when it differs from the profile's. | | `Port` | No | A whole number. Saved for the device only when it differs from the profile's. | | `Enterprise`, `Site`, `Area`, `ProcessCell`, `EquipmentModule` | No | Where the device sits. Free text, the same levels as in the setup wizard. | | `DeviceType` | No | What the machine is, as the device type list shows it, for example `Filler / Packaging` or `Motor / Drive`. | | `Enabled` | No | `true` or `false` (`1`, `0`, `yes` and `no` also work). A new device is enabled when the cell is empty. | Headers are not case-sensitive, and the Turkish headers of the template are read as well. A column the import does not know is ignored, and the first step says which ones. For a device that already exists, an empty cell keeps its current value. So a file with only `DeviceName` and `Site` moves devices to another site and changes nothing else. ```text DeviceName,Profile,Gateway,Host,Port,Enterprise,Site,Area,ProcessCell,EquipmentModule,DeviceType,Enabled LYS_PACKER_04,Case packer,SYSTEM,127.0.0.1,5020,Meridian,Lyon Foods Plant,Packaging,Line 4,,Filler / Packaging,true LYS_PACKER_21,Case packer,SYSTEM,10.20.4.41,502,Meridian,Lyon Foods Plant,Packaging,Line 5,,Filler / Packaging,true ``` ## Step 1: Choose the file Go to **Connect > Import Devices**. *Screenshot: The first import step with the file box, the list of columns and the two template buttons* 1. Select the file box and choose your file. It then shows the file name and the number of rows. 2. The columns the import reads, for reference. 3. The template buttons, if you do not have a file yet. Select **Next: Dry run**. ## Step 2: Check the dry run Each row is compared with what already exists in Proxus. Nothing is saved yet. *Screenshot: The dry run with one row to change, one to add and one with an error because its profile does not exist* 1. The counters filter the table: **All**, **To add**, **To change** and **Errors**. When there are errors, the table opens on **Errors**. 2. Each row shows its device, profile, gateway and address, and the result: **Add**, **Change** (with each change listed, old value and new value), **No change** or **Error** (with the reason). 3. **Test the connections first** (optional): each new or changed device is tried from its own gateway, and the row shows **Connection OK** or the reason it failed. Nothing is saved by the test. 4. **Apply** saves the rows that are to be added or changed. The button shows how many. Rows with an error are skipped. To include them, fix the file, select **Back** and choose the file again. ### Errors the dry run reports | Message | What to do | | --- | --- | | No device name | Fill in `DeviceName`. | | “…” appears more than once in the file | Keep each device name on one row only. | | “…” does not follow the naming rule | Your administrator set a naming rule for new devices. Rename the device to match it. | | No profile / Profile “…” not found | Enter the exact name of an existing device profile. | | No gateway / Gateway “…” not found | Enter the exact name of an existing edge gateway. | | Port “…” is not a number | Enter the port as a whole number, or leave it empty. | | Device type “…” not known | Use a device type as the list shows it. | | Active must be true or false | Enter `true` or `false` in `Enabled`. | | Address … is already used by … | Two devices cannot have the same address and port. Check the `Host` and `Port` columns. | ## Step 3: Done The last step says how many devices were added and changed. All of them are saved together. The devices are on their gateways right away; select **Open the device list** to see them, and open a device to see its first values. > **Note:** Run the same file again at any time. Devices that already match the file show **No change** and are not touched, so a corrected file only applies what is new. ## What's next - [The device page](https://proxus.io/docs/connect/devices/device-page): check that each device sends values. - [Change a device](https://proxus.io/docs/connect/devices/configure-a-device): adjust one device with the setup wizard. - [Import from Kepware](https://proxus.io/docs/connect/devices/kepware-import): bring devices and their tags over from a Kepware server. --- # Import from Kepware > Bring channels, devices and tags from a running Kepware server into Proxus, converted to the matching Proxus protocol, after a review of every change. Source: https://proxus.io/docs/connect/devices/kepware-import At the end of this guide, the Kepware devices you chose exist in Proxus as devices with their tags, and they run on the edge gateway you picked. Proxus reads the project directly from the Kepware server. Nothing changes on the Kepware side. ## Before you start You need: - A **Kepware server** with its **Configuration API** turned on, and a user name and password for that API. The hub must reach the server on the API's port (57512 by default, with HTTPS). - The **edge gateway** that will read the imported devices. It must reach the same machines that Kepware reads. - A user role that may create devices and device profiles. > **Note:** The importer reads the project from the running server. It does not open a saved project file (`.opf` or `.json`). ### What can be imported Each Kepware channel uses a driver. The importer converts these drivers: | Kepware driver | Proxus protocol | | --- | --- | | A Siemens driver | Siemens S7-200, S7-300, S7-400, S7-1200 or S7-1500, from the device model. S7-200 SMART is recognised by its model name. A device without a model becomes S7-1500. | | A Modbus Ethernet driver | Modbus TCP | | The OPC UA client driver | OPC UA | Other drivers, Siemens NetLink models and Modbus serial channels are listed but cannot be selected. ## Step 1: Connect Go to **Connect > Kepware Project Importer**. The importer opens in a window. *Screenshot: The Kepware connect step with host, port, protocol, user name and password fields and the Test connection button* 1. Enter the **Host** of the Kepware server and its **Port**. Choose **HTTPS** or **HTTP** under **Protocol**, then fill in **Username** and **Password** for the Configuration API. 2. Select **Test connection**. When it works, the box shows the project name and how many channels, devices and tags it holds. 3. **Advanced**: if the server uses Kepware's own self-signed certificate, tick **Allow an invalid certificate**. Do this only on a network you trust. Select **Continue**. If the test fails, the message says why. "The server's certificate is not trusted" means a self-signed certificate (see point 3). "The TLS handshake failed" means the port does not serve HTTPS: switch to **HTTP** or check the port. ## Step 2: Select The project is shown as a tree of channels and their devices. Each line shows the Proxus driver it becomes and its number of tags. 1. Tick the channels or single devices to import. Use the search box to find them by name, and **Select all** or **Clear** for the whole list. 2. Lines marked **Not supported** use a driver the importer cannot convert. 3. The counter shows how many tags in how many devices you selected. Select **Review**. The button shows the number of tags. ## Step 3: Review The importer reads every selected tag and checks its address and data type. Nothing is written yet. 1. The tiles show the **New devices**, the **Updated devices** (a device with the same name already exists in Proxus) and the number of **Tags**. 2. **Errors** stop the import, for example a tag address that cannot be converted. Go back and leave the device out, or fix it in Kepware. 3. **Warnings** do not stop the import. They list tags that are imported with a different data type (see below). 4. **Run on gateway**: the edge gateway that reads the new and updated devices. **SYSTEM** is chosen by default. You can move devices to another gateway later. Select **Import**. The button shows the number of tags. ## Step 4: Import A progress bar and a log show each device as it is created or updated. You can select **Run in background** and close the window; a notification tells you when the import ends. When it is done, select **Open devices**. The devices start sending values as soon as their gateway picks up the new configuration. ## How Kepware items become Proxus items - Each Kepware device becomes one **device profile** and one **device**, both named `Kepware__`. Characters other than letters, digits, `_` and `-` become `_`. - Each Kepware tag becomes a **tag** of that profile. Tag groups are flattened; the tag keeps its Kepware name. - Addresses are converted to the form Proxus reads, for example a Modbus `400001` becomes `x=3;0`. - The connection settings come with the device: address, port, unit ID and byte order for Modbus; rack, slot and timeouts for Siemens; endpoint and security for OPC UA. - The profile's polling interval is the scan rate most tags of the device use (1000 ms if none is set). A tag with another scan rate keeps its own. - Importing again updates the same devices in place: profiles and devices are matched by name, tags by address. ### Data types | Kepware | Proxus | | --- | --- | | Boolean | Bool | | Byte | Bytes (1 byte) | | Char | String (1 character), with a warning | | Short | Short | | Word | UShort | | Long | Int | | DWord | UInt | | LLong | Long | | QWord | ULong | | Float | Float | | Double | Double | | String | String | | Date | DateTime | | BCD, LBCD | UShort, UInt: the raw register value, not decoded. Proxus has no BCD type, so a warning is shown. | Arrays are imported as bytes or as text, with a warning. An unknown type becomes String, with a warning. > **Warning:** Kepware does not export passwords. An OPC UA device that signs in with a user name is imported without its password. Enter it in the device profile's **Connection Parameters** after the import, or the device cannot connect. ## What's next - [The device page](https://proxus.io/docs/connect/devices/device-page): check that each imported device sends values. - [Device profiles](https://proxus.io/docs/connect/device-profiles): adjust the imported connection settings and tags. - [Import devices from a spreadsheet](https://proxus.io/docs/connect/devices/import-devices): add more machines of the same kinds. --- # Connect an OPC UA server > Find OPC UA servers from the gateway, choose how to connect, trust certificates on both sides, and pick the nodes to read. Source: https://proxus.io/docs/connect/devices/opc-ua At the end of this guide, an OPC UA server (a PLC, an HMI, a SCADA server or a gateway product) is a device in Proxus, connected securely if the server allows it, and the nodes you picked are read as tags. ## Before you start You need: - The OPC UA server running and reachable from the gateway, usually on port 4840. You may know its endpoint URL (`opc.tcp://host:port/path`), or let the gateway find it. - Access to the server's certificate settings if you connect with security: the server must trust the gateway's certificate. - For sign-in with a user name: the user name and password. - A gateway on the server's network. See [Add a device](https://proxus.io/docs/connect/devices/add-a-device) for the general steps of the wizard. ## Step 1: Choose OPC UA In **Connect > Devices**, select **New**. Choose the gateway, select the **OPC UA** card and **Next: Connection**. ## Step 2: Find the server *Screenshot: The Find servers panel with one server found and three ways to connect: anonymous, client certificate and user name, all signed* 1. Select **Discover servers**. The gateway looks for OPC UA servers on its network; this can take up to 15 seconds. 2. **Discovery URL** (optional): if the server or a discovery server is not found, enter its address here, for example `opc.tcp://192.168.1.20:4840`, and search again. 3. Each way to connect is listed under its server: the endpoint URL, the security (**No security**, **Sign** or **Sign & encrypt** with the security policy) and the sign-in (**Anonymous**, **User name**, **Client certificate** or **Issued token**). The best one is marked **Recommended for production**. Select one. Selecting a way to connect fills in **Endpoint Url**, **Security Mode**, **Security Policy** and **User Token Type** under **Address**. If you already know the endpoint, you can type these directly instead of searching. What the gateway searches: - **Check well-known local addresses** (on by default): the gateway's own machine and the container host, on the usual OPC UA ports. - **Scan the gateway's subnet** (off by default): every host in the gateway's /24 network. Slower on large networks. > **Tip:** Prefer **Sign & encrypt**, or at least **Sign**, in production. **No security** sends values that anyone on the network can read and change; use it only on a test network. For **User name**, enter **User name** and **Password** under **Address**. The password is not kept in the wizard's draft, so enter it again if you leave the wizard and come back. ## Step 3: Trust the certificates A secure connection needs trust on both sides: the gateway trusts the server, and the server trusts the gateway. When you choose a way to connect with security, the **Certificates** panel appears and checks both. *Screenshot: The Certificates panel showing the server trusted by gateway SYSTEM and the server accepting Proxus, each with its fingerprint* 1. **The server's certificate.** If the gateway does not trust it yet, compare the fingerprint shown with the one on the server, then select **Trust this server**. The line then shows **Trusted by gateway** and the gateway's name. The certificate is recorded as trusted in the Certificate Store, so every gateway accepts it. 2. **The gateway's certificate on the server.** If the server does not trust the gateway yet, the panel shows the name of the gateway's certificate and **Copy fingerprint**. In the server's certificate settings, move that certificate from rejected to trusted (on a Prosys simulation server: **Certificates**, **Rejected**, **Trust**). Then select **Check now** until the line shows **The server accepts Proxus**. Each gateway has its own OPC UA certificate. A server that talks to two gateways must trust both. Select **Test the connection**, then **Next: Tags**. ## Which server certificates the gateway accepts Device connections and tag browsing never accept an unknown server certificate. A gateway accepts only: - certificates the [Certificate Store](https://proxus.io/docs/administer/certificates) trusts for OPC UA, and - the server certificate pinned on the device (the trusted server certificate in the device profile's OPC UA settings). The store is the one place for this decision. Every gateway copies the store's OPC UA trust list every minute, so **Trust** or **Reject** in the store takes effect on all gateways within a minute. When a gateway refuses a certificate, it reports it to the hub. To accept it: 1. Go to **Security > Certificate Store** and open **Trust View**, **Rejected**. The certificate is named `OPC UA server (
)`. 2. Compare the fingerprint with the one on the server, select the certificate and select **Trust**. The refused devices connect at their next retry. **Trust Server Certificate** on a device trusts the server on first sight: the certificate is accepted at the first connection and recorded as trusted in the store, where you can see it and withdraw it with **Reject**. It does not re-open a certificate that the store has rejected. Devices with the security mode **None** do not use certificates and are not affected. > **Warning:** Trust decisions made locally on a gateway before 2.0.0 no longer count. After the upgrade, OPC UA devices that use **Sign** or **Sign & encrypt** send no data until their server certificate is trusted in the store. Right after upgrading, open **Trust View**, **Rejected** and **Trust** each server you recognise. ## Step 4: Pick the nodes *Screenshot: The From the device tab inside the Simulation folder with seven variables listed and three of them ticked* 1. On the **From the device** tab, select **Browse the device**. The list starts at **Objects**. Select a folder to open it; the path above the list takes you back. 2. Tick the variables to read. Each shows its name, its node ID, its type and its current value. Use the filter box to find a variable in a long folder. 3. Select **Add … to the list**. The variables become tags in the table. The **Address** of an OPC UA tag is the node ID, for example `ns=3;i=1001` or `ns=2;s=Line1.Speed`. You can also type node IDs in the **Table** or **Paste** tabs. The data type is taken from the node: | OPC UA type | Proxus type | | --- | --- | | Boolean | Bool | | SByte, Int16 | Short | | Byte, UInt16 | UShort | | Int32 | Int | | UInt32 | UInt | | Int64 | Long | | UInt64 | ULong | | Float | Float | | Double | Double | | DateTime | DateTime | | ByteString | Bytes | | Arrays and other types | String (the value as text) | Continue with **Place and type** and **Save and verify** as for any device. ## How values are read The gateway reads all tags of the device together, once per **Read every** interval. It does not use OPC UA subscriptions, so there is no publishing or sampling interval to set: choose **Read every** for how fresh the values must be. ## The OPC UA wizard on a profile A device profile with the OPC UA protocol has its own connection wizard, **Connect to OPC UA**. Open it from the profile's **Tags** tab with **Discover Servers** (it starts at finding the server) or **Browse Tags** (it starts at the tags). Its steps are **Discover**, **Connection**, **Sign in**, **Trust**, **Tags** and **Review**, and **Save to profile** saves the connection and the tags to the profile. Devices that use the profile get the new settings at the gateway's next sync. Use it to change the connection or the tags of every device of a profile at once, or to sign in with a **client certificate**: its **Sign in** step lets you pick a certificate from the hub's certificate store. Import the certificate first under [Certificates](https://proxus.io/docs/administer/certificates). ## The ports the gateway tries Discovery tries these ports on each host: 4840 and 53530 (`opc.tcp`) and 53443 (`https`). To change them, or to give discovery servers that every search should ask, edit the `[Browse]` section of the gateway's configuration file: ```toml [Browse] OpcUaDiscoveryPorts = "tcp:4840, tcp:53530, https:53443" OpcUaSeedDiscoveryUrls = "opc.tcp://lds.example.local:4840" ``` ## What's next - [The device page](https://proxus.io/docs/connect/devices/device-page): check the live values. - [Device profiles](https://proxus.io/docs/connect/device-profiles) - [Troubleshoot devices](https://proxus.io/docs/troubleshoot/devices) --- # Connect an MTConnect machine > Find the MTConnect agents on the gateway's network, pick a machine, and choose its data items from the agent's own list. Source: https://proxus.io/docs/connect/devices/mtconnect At the end of this guide, a CNC machine or other equipment that has an MTConnect agent is a device in Proxus, and its data items (execution state, spindle speed, part count and others) are read as tags. Proxus reads the agent over HTTP: the machine's agent serves its data items, and the gateway asks it for new values at each read. Nothing has to be installed on the machine. ## Before you start You need: - An **MTConnect agent** for the machine, running and reachable from the gateway over HTTP. Agents usually listen on port 5000. You may know its address, or let the gateway find it. - A gateway on the agent's network. See [Add a device](https://proxus.io/docs/connect/devices/add-a-device) for the general steps of the wizard. ## Step 1: Choose MTConnect In **Connect > Devices**, select **New**. Choose the gateway, type `mtconnect` in the protocol search box and select the **MTConnect** card. Select **Next: Connection**. ## Step 2: Find the agent *Screenshot: The Find agents panel with one agent found on port 5005 serving the machine Mill, selected* 1. Select **Find agents**. The gateway asks its network for MTConnect agents; with a subnet scan this can take up to 30 seconds. 2. **Agent address** (optional): if you know the agent, enter it here, for example `192.168.1.20:5000`. A host name alone is tried on every usual agent port. You can enter several, separated by commas. 3. Each agent found is listed by its URL, with the machines it serves: name, maker and model, and the machine's ID. Select a machine. Its address and port are filled in under **Address**. What the gateway searches: - **Check this machine** (on by default): the gateway's own machine, and the container host, on the usual agent ports. - **Scan the gateway's subnet** (off by default): every host in the gateway's /24 network. Slower on large networks. If no agent answers, enter the agent's address under **Agent address**, or type the **IP address** and **Port** of the agent directly under **Address**. Select **Test the connection** to check that the gateway reaches the agent, then **Next: Tags**. ## Step 3: Choose the data items *Screenshot: The From the device tab listing the data items of the Mill machine with four of them ticked and the Add 4 to the list button* 1. Select the **From the device** tab. 2. Select **Browse the device**. The gateway reads the agent's list of data items, with their current values. Use the filter box to find items by name or address. 3. Tick the data items to read. Items the agent itself publishes (named after the agent) are listed too; you usually only need the machine's own. 4. Select **Add … to the list**. The items become tags in the table. Each tag's **Address** is the machine's name, the component path and the data item, separated by `/`, for example `Mill/controller/exec` or `Mill/avail`. Units come from the agent. The data type is chosen from the kind of data item: positions, speeds, temperatures and loads become numbers, counts become whole numbers, and states such as execution or availability become text. Continue with **Place and type** and **Save and verify** as for any device. ## How values are read - At each read, the gateway asks the agent for the values since its last read, so short changes between two reads are not lost. If that fails, it reads the current values instead and tries again later. - A data item that the agent reports as `UNAVAILABLE` has quality **Uncertain**. A condition in **Fault** has quality **Bad**; a condition in **Warning** has quality **Uncertain**. ## The agent ports the gateway tries Discovery tries these ports on each host: 5000, 5001, 5005, 5006 and 7000. To change the list, set `MtConnectDiscoveryPorts` in the `[Browse]` section of the gateway's configuration file: ```toml [Browse] MtConnectDiscoveryPorts = "5000, 5001, 5005, 5006, 7000" ``` As an environment variable, the same key is `Browse__MtConnectDiscoveryPorts`. The search runs on the gateway, so set it on the gateway that searches. ## What's next - [The device page](https://proxus.io/docs/connect/devices/device-page): check the machine's live values. - [Troubleshoot devices](https://proxus.io/docs/troubleshoot/devices) --- # Simulated devices > Add a device that produces values on the gateway itself, to try trends, rules, pipelines and dashboards without a real machine. Source: https://proxus.io/docs/connect/devices/simulator At the end of this guide, a simulated device sends values like a real machine: a temperature that swings, a speed that drifts, a running signal that turns on and off. Use it to build and test trends, rules, pipelines and dashboards before the real machine is connected, or for a demo. The **Simulator** protocol runs on the gateway itself. There is no address to reach and nothing to install. ## Before you start You need a gateway that is online. The hub's own gateway, **SYSTEM**, works. ## Add a simulated device Follow [Add a device](https://proxus.io/docs/connect/devices/add-a-device), with these differences. ### Step 1: Protocol and gateway Type `simulator` in the protocol search box and select the **Simulator** card. ### Step 2: Connection *Screenshot: The connection step for the simulator with only the Read every field and a passed test* 1. **Read every**: how often the gateway produces a new value for each tag. Leave **Profile default** or choose an interval. 2. **Test the connection** is optional. It only confirms that the gateway is ready to produce values. ### Step 3: Tags For the simulator, a tag's **Address** is the range the value stays in, and the **Pattern** column says how the value moves inside that range. *Screenshot: The simulator tag table with three tags: OvenTemp with a sine wave, BeltSpeed with a random walk and Running with a square wave, each with a test value* 1. The tabs to add tags. **Paste** also takes a fifth column with the pattern name. 2. The tag table: **Name**, **Address**, **Type**, **Unit**, **Pattern** and the **Test read** value. 3. **Pattern** of each tag. See [Patterns](#patterns). 4. **Read all once** produces one value for each tag, so you can check the ranges. The quickest way to add tags is the **Address helper** under the table: *Screenshot: The address helper with name BatchCount, minimum 0, maximum 5000, unit pcs, type Int and the cycle pattern, building the address [0,5000]* 1. **Minimum** and **Maximum**: the range of the value. 2. **Pattern**: how the value moves. 3. The address the helper builds, for example `[0,5000]`. 4. **Add to the list** adds the tag to the table. Fill in **Name**, **Unit** and **Type** as well. Then continue with **Place and type** and **Save and verify** as for any device. ## Addresses | Address | Meaning | Example | | --- | --- | --- | | `[min,max]` | A value between `min` and `max`. Use a full stop for decimals. | `[180,220]`, `[-5.5,40]` | | `model:Asset/Signal` | A signal of the demo plant model. The value follows the plant's simulated production, with stops, faults and changeovers. | `model:LYS.P1.CSP/Speed` | | `model:{device}/Signal` | The same, for the asset whose device name is the device's own. Used by the demo profiles, so one profile serves every machine of a kind. | `model:{device}/GoodCount` | A text tag (type String) may have an empty address. It then gets a random text of ten letters and digits. A **Bool** tag is `true` when its value is above 0, so `[0,1]` with **Square wave (on/off)** gives a running signal. A **DateTime** tag gets a random date in the last year. > **Note:** `model:` addresses and `{device}` work only with the assets and device names of the demo plant model that comes with the demo data (for example `MFB_LYS_P1_CASEPACKER`). For a device of your own, use a `[min,max]` range. ## Patterns | Pattern | How the value moves | | --- | --- | | **Random** | A new random value in the range at each read. | | **Random walk** | Small steps up or down from the middle of the range. | | **Sine wave** | A smooth wave between minimum and maximum. | | **Triangle wave** | Rises and falls in straight lines. | | **Sawtooth** | Rises in a straight line, then drops back. | | **Square wave (on/off)** | Stays at the maximum, then at the minimum, for equal times. | | **Steps** | Moves in ten steps through the range. | | **Around the middle (Gaussian)** | Random, mostly near the middle of the range. | | **Smoothed noise** | Random, but without sudden jumps. | | **Cycle (ramp, hold, fall)** | Ramps up, holds, then falls, like a machine cycle. | | **Composite (wave and noise)** | A wave with noise on top. | | **Plant model** | Follows the demo plant model. Required for a `model:` address. | Without a pattern, a `[min,max]` tag uses **Random** and a `model:` tag uses **Plant model**. ## What's next - [The device page](https://proxus.io/docs/connect/devices/device-page): watch the simulated values and open their trends. - [Rules](https://proxus.io/docs/automate/rules): try an alarm on a simulated value. - [Your first machine](https://proxus.io/docs/get-started/first-machine): the guided tutorial that uses the simulator. --- # Install an edge gateway > Run an edge gateway on a Linux machine next to your machines. The hub gives you a one-line command, and shows each install stage live. Source: https://proxus.io/docs/connect/edge-gateways/install-a-gateway At the end of this guide, a new edge gateway runs on a machine in your plant, is connected to the hub, and is ready to read devices. An edge gateway is the Proxus runtime that sits close to the machines: it reads them, keeps the data when the hub cannot be reached, and sends it on. The hub has its own gateway, **SYSTEM**. You need an edge gateway only for machines that the hub cannot reach, or to keep reading when the network to the hub is down. ## Before you start You need: - A **Linux machine** (Ubuntu, Debian, Red Hat Enterprise Linux or an industrial PC) on the network of the machines. Windows is not supported yet. - **Docker** 20.10 or later with the **Compose** plugin on that machine, and a user who may run `sudo`. - From that machine, outbound access to the hub on **port 7422** and on the hub's HTTPS port (**8443** by default). The gateway connects out to the hub; no port has to be opened towards the plant network. - Ports **8083**, **1883** and **8883** free on that machine. The gateway uses them for its local web service, its MQTT broker and its MQTT broker over TLS. - Access to Docker Hub from that machine, so it can download the gateway image. Without it, load the image on the machine beforehand with `docker load`, as in [Install without internet access](https://proxus.io/docs/operate/offline-install#install-edge-gateways-on-the-closed-network). - A user role that may create edge gateways. ## Step 1: Create the gateway in the hub 1. Go to **Connect > Edge Gateways** and select **New**. 2. Enter a **Name**, for example `Rotterdam Edge 01`, and optionally a **Location**, for example `Rotterdam, filling hall`. Both are under **Configuration**. 3. Select **Save**. The install window opens by itself after the first save. To open it later, select **Install** on the gateway's page. ## Step 2: Choose the environment *Screenshot: The first install step with Linux with Docker selected and the hub address chosen* 1. **Linux with Docker** is selected. The machine's processor type is detected during the install. 2. **Hub address**: the address the edge machine uses to reach the hub. The list offers, in this order, the address you opened the hub on (when it is not `localhost`), the machine's address that the hub installer detected, and the hub's public internet address. For an edge machine on another site, choose the public address and forward ports 7422 and 8443 to the hub, or select **Another address** and enter a DNS name. When you create the command, the hub adds this address to the certificate of its NATS server, so the gateway's TLS check succeeds. If the list is empty, the hub could not tell which address other machines reach it on. Enter the machine's IP address or host name in **Another address**. **Advanced** shows the ports used on the edge machine, the outbound connection to the hub and the folder the gateway is installed in (`/opt/proxus/proxus-edge-`). Select **Continue**. ## Step 3: Run the command on the edge machine *Screenshot: The command step with a curl command to run on the edge host, a Copy button and the list of requirements* 1. The install command. It downloads an installer from the hub and runs it. 2. **Copy** puts the command on the clipboard. 3. **Before you run it**: the requirements, with the hub address you chose. Open a terminal on the edge machine, paste the command and run it. It looks like this: ```bash curl -fsSL -k --pinnedpubkey sha256// https://hub.example.com:8443/edge/ | sudo sh ``` The command downloads the installer over HTTPS and is pinned to the hub's HTTPS key (`--pinnedpubkey`). `curl` accepts only the hub that holds that key, whatever certificate the hub has, so nobody on the way can swap the installer or the gateway's identity. Every call the installer makes to the hub uses the same pin. When HTTPS is off on the hub, the command uses plain `http://` on the hub's web port, as in earlier releases. The link works once, and only for one hour. The command carries no secret: the gateway creates its own key on the edge machine, and only the public key is sent to the hub. Select **I ran the command**, or wait: the window moves on by itself when the edge machine downloads the installer. ## Step 4: Watch it connect The last step follows the install live. Each line turns green in order: 1. **Installer downloaded on the host** 2. **Gateway image downloaded** 3. **Gateway key registered with the hub** 4. **Gateway started** 5. **Connected to this hub** When **The gateway is connected** appears, select **Add devices** to add the first device to this gateway, or **Close**. In **Connect > Edge Gateways**, the gateway now shows **Online**. You can close the window at any time; the install continues on the edge machine, and the gateway's page shows when it connects. ## What the installer does On the edge machine, the installer: - checks Docker, Compose and the free ports (the service port, `1883` and `8883`); - creates the folder `/opt/proxus/proxus-edge-` with the gateway's settings; - downloads the images and creates the gateway's key; - registers the public key with the hub, and reports the machine's names and addresses; - sets up the gateway's link to the hub as TLS, checked against the platform CA that the installer brings along (public certificates only); - starts two containers, the gateway and its local message broker, which restart by themselves after a reboot. It touches nothing else on the machine. ## The gateway's certificate Each gateway gets its own certificate from the hub's [Certificate Store](https://proxus.io/docs/administer/certificates), named "*gateway name* (gateway *N*)". It covers the names and addresses the installer reported, and it is used for the gateway's MQTT broker over TLS (port `8883`) and its optional HTTPS port. - The gateway asks for it when it starts and twice a day. The hub renews it in the store before it expires. - The gateway keeps the last certificate it received, so it still has one after a restart while the hub cannot be reached. - A gateway can only get its own certificate. - When the certificate is renewed, the MQTT broker restarts for a few seconds and devices reconnect. MQTT devices check the broker against the platform CA: install it on them from **Security > Certificate Store**, **Download CA**, and connect to a name or address that the certificate covers. ## Troubleshooting If a stage fails, the window says which, and the terminal on the edge machine shows the details. Fix the cause, then select **Create a new command** and run the new command. | Message | What to do | | --- | --- | | Docker is missing, not running, or this user cannot use it. | Install or start Docker, then run a new command. | | A port the gateway needs (8083, 1883 or 8883) is in use on the host. | Stop the program that uses the port. The terminal names it. | | The gateway image could not be downloaded. | Check that the edge machine reaches Docker Hub, or load the image beforehand. | | The gateway could not register its key with the hub. | The command was already used or has expired. Create a new command. | | The containers could not start. | The terminal on the edge machine shows why. Fix it, then create a new command. | If `curl` stops with an error about the public key, the hub's HTTPS certificate changed after the command was created. Create a new command. If the gateway started but does not connect, check that the edge machine reaches the hub on port 7422. For more, see [Troubleshoot gateways](https://proxus.io/docs/troubleshoot/gateways). ## What's next - [Add a device](https://proxus.io/docs/connect/devices/add-a-device) and choose this gateway in the first step. - [Manage edge gateways](https://proxus.io/docs/connect/edge-gateways/manage-gateways): status, logs, buffer, update and remove. --- # Manage edge gateways > See whether each edge gateway is online, read its logs, set how long it buffers data, update or remove it, and revoke its access to the hub. Source: https://proxus.io/docs/connect/edge-gateways/manage-gateways All edge gateways are listed in **Connect > Edge Gateways**, with the hub's own gateway, **SYSTEM**. Select a gateway to open its page. ## The list *Screenshot: The edge gateway list with two online gateways, their devices, capacity, CPU, memory and system* 1. **New** creates a gateway. See [Install an edge gateway](https://proxus.io/docs/connect/edge-gateways/install-a-gateway). 2. **Latest Status**: whether the gateway is connected, and for how long. 3. **Capacity**: how much of the licensed data rate the gateway uses. | Column | What it shows | | --- | --- | | **Gateway** | The gateway's name. | | **Latest Status** | See [Status](#status). | | **Devices** | Devices sending data, out of all devices on this gateway, for example `74 / 75`. **None** if it has no devices. | | **Capacity** | The share of the licensed data rate, and **Healthy**, **Warning**, **Critical** or **Exceeded**. **Stale** when the gateway has not reported for more than 30 seconds. | | **CPU**, **Memory** | What the gateway process uses on its machine. Empty while the gateway is offline. | | **System** | The operating system, processor and memory of the gateway's machine. | ### Status | Status | Meaning | | --- | --- | | **Online (for …)** | Connected to the hub, for the time shown. | | **Never connected** | The gateway was created but has not been installed, or has not connected yet. | | **Last seen … ago** | The gateway was connected and has stopped reporting. | | **Not responding** | The connection to the hub is up, but the gateway sends nothing. | | **Connection refused** | The hub refused the gateway's connection, for example because its key is no longer valid. | | **Access revoked** | Its access was revoked. It connects again only after a new install. | ## The gateway page *Screenshot: The page of the Rotterdam Edge 01 gateway with the Logs, Install and Revoke access buttons and its figures* 1. **Logs**: the gateway's entries in the system log. 2. **Install**: install, update or remove the gateway on its machine. 3. **Revoke access**: disconnect the gateway from the hub at once. 4. **Devices sending data**, **Capacity**, **CPU**, **Memory** and **Last seen**. When the gateway is not connected, a sentence under its name says why and what to check, for example "Check the host and that it reaches the hub on port 7422." The tabs below show: | Tab | What it shows | | --- | --- | | **Metrics** | The license capacity of the gateway and a chart of its load. | | **Devices** | The devices this gateway reads. | | **Functions**, **Rules**, **Pipelines** | What runs on this gateway. | | **Access history** | Each install, connection, disconnection and revocation, with the time, the address and the user. | ### Configuration Open **Configuration** at the bottom of the page: | Field | What it is | | --- | --- | | **Name** | A unique name. Required. | | **Location** | Where the gateway is, for example `Rotterdam, filling hall`. | | **Buffer Retention (hours)** | How long the gateway keeps data it could not deliver to the hub. Default 48, from 1 to 720. | | **Source Domain** | Leave empty. It is needed only for some partner-managed installations. | | **System Info** | The gateway's machine, as the gateway reports it. Read only. | > **Warning:** **Buffer Retention (hours)** needs disk space on the edge machine for that many hours of data at the gateway's data rate. Lowering it drops buffered data older than the new limit. The new value is sent to the gateway when you save; a gateway that is offline gets it when it connects again. ## Actions | Action | What it does | | --- | --- | | **Install** | Opens the install window: a new command installs the gateway, or updates an installed gateway to the hub's current version and keeps its data. The command is pinned to the hub's HTTPS key and sets up the gateway's TLS link to the hub. Under **Remove from its host**, the window shows the command that removes the gateway's containers, data and folder from its machine; nothing else on the machine is touched. The remove command is pinned the same way. | | **Logs** | Opens the system log entries of this gateway. **Refresh** reloads them; select an entry to read the whole message. On the edge machine itself, `docker logs` shows the container's output. | | **Terminal** | Opens a command terminal to the gateway, after a confirmation. | | **Revoke access** | Disconnects the gateway from the hub within seconds; its key stops working, and its devices stop sending data to the hub. It connects again only after a new install command is run on its machine. Proxus asks for confirmation first. | | **Audit Trail** | Who changed the gateway's settings, and when. | | **Delete** | Deletes the gateway and revokes its key. | > **Danger:** **Revoke access** stops the data of every device on that gateway from reaching the hub. Use it when a gateway machine is lost, stolen or replaced, not to pause a gateway. > **Warning:** Gateways installed before 2.0.0 cannot connect to the hub after the upgrade, because the hub's message server now requires TLS. Select **Install** on each of them and run the new command on its host. Until then the gateway keeps reading and buffers its data for **Buffer Retention (hours)**, then sends it. ## The gateway's certificate Each gateway has its own certificate in **Security > Certificate Store**, named "*gateway name* (gateway *N*)", with the usage **Gateway HTTPS** and **MQTT Broker**. The hub issues it, covers the names and addresses the gateway's host reported at install, and renews it before it expires. The gateway uses it for its MQTT broker over TLS (port `8883`) and its optional HTTPS port. **Used By** on the certificate shows which gateway uses it. See [Install an edge gateway](https://proxus.io/docs/connect/edge-gateways/install-a-gateway#the-gateways-certificate). ## The SYSTEM gateway **SYSTEM** runs inside the hub. It cannot be deleted, installed, revoked or renamed, and it has no buffer setting. Use it for devices that the hub itself can reach. ## What's next - [Install an edge gateway](https://proxus.io/docs/connect/edge-gateways/install-a-gateway) - [Troubleshoot gateways](https://proxus.io/docs/troubleshoot/gateways) - [System logs](https://proxus.io/docs/administer/system-logs) --- # Organize > Find any tag in the Unified Namespace, see what depends on what, check the setup for broken links and wasted data, and package objects as templates. Source: https://proxus.io/docs/organize **Organize** is about how your setup fits together. Here you find where a value lives in the plant, which rules and targets use it, what in the configuration is broken or wasted, and how to reuse a set of objects on another hub. In the hub, these screens are in the **Organize** menu. ## The screens | Screen | What it is for | | --- | --- | | **UNS Explorer** | The Unified Namespace as a live tree: enterprise, site, area, line, device and tag, with the current value, quality and a short trend of every tag. | | **Health Checks** | Checks every configured object and lists what is broken, what needs a look and what is collected for nothing. **Trace an object** shows what one object depends on and what it feeds. | | **Application Templates** | Packages devices, profiles, rules, functions and other objects into a template that can be exported, imported and installed. | Every device, rule, function, dashboard and outbound target also has a **Dependencies** action on its own page, and Proxus shows what depends on an object before you delete or switch it off. ## Start here ## Background The structure of the tree comes from the place each device is given: see [Unified Namespace](https://proxus.io/docs/concepts/unified-namespace). Who may see which part of it is set per role: see [UNS permissions](https://proxus.io/docs/administer/uns-permissions). --- # UNS Explorer > What the UNS Explorer shows. The live Unified Namespace tree with values, quality and trends, the selection panel, search, export and the right-click menu. Source: https://proxus.io/docs/organize/uns-explorer The **UNS Explorer** shows the Unified Namespace (UNS) as a live tree. Every device sits at the place it was given (enterprise, site, area, line and so on) and every tag under its device, with its current value. It is in **Organize > UNS Explorer**. Values update by themselves while the page is open. You see the parts of the tree your role may read. With no access at all, the page says **UNS access is not granted for your role.** See [UNS permissions](https://proxus.io/docs/administer/uns-permissions). *Screenshot: The UNS Explorer filtered to MFB_RTM_L1_FILLER, the tree expanded from Meridian down to the filler's tags, and the Speed tag selected in the panel* 1. The summary and the search box. The summary shows the devices online, the number of tags, the updates per minute and the latency. 2. A device node. Group nodes show how many devices and tags are under them. 3. A tag, with its value, a trend and when it was updated. 4. The panel: details of what is selected. 5. **Open trend** opens the tag's trend. ## The summary | Figure | Meaning | | --- | --- | | **devices online** | Devices online, out of all devices in the tree. | | **tags** | Tags in the tree. | | **updates/min** | Values received per minute, measured over 10 seconds. | | **latency** | End-to-end age: the time between the value's own timestamp and now. | ## The tree Each row has a **Node**, a **Value**, a **Trend** and when it was **Updated**. Next to a group node, a short label says its level: **ENT** (enterprise), **SITE**, **AREA**, **CELL** (process cell) and so on, down to **DEVICE**. A device with no place sits at the top of the tree. | Column | What it shows | | --- | --- | | **Node** | The name of the level, device or tag. A tag with bad quality has an **ERR** badge. | | **Value** | The tag's current value with its unit. A tag that cannot be read shows its error. | | **Trend** | The values received since you opened the page, with the change in percent. Text tags have no trend. | | **Updated** | When the value last arrived. | Names in the namespace replace spaces with underscores: the site **Rotterdam Beverage Plant** is the node `Rotterdam_Beverage_Plant`. Type in **Search...** and press Enter to keep only the branches that contain a match. The branches start collapsed: right-click a node and choose **Expand All** to open them. The filter funnel in a column header filters by that column. Clear the search box to show the whole tree again. The button next to the search box exports the tree as **Excel (XLSX)**, **Excel 97 (XLS)** or **CSV**. The export has an extra column, **Outbound**, with the targets each device sends its data to. ## The panel Select a row to see it in the panel on the right. Its path is shown under the name; **Copy** puts the path on the clipboard. | Selected | The panel shows | | --- | --- | | A tag | The value and its quality (**Good** or **Bad quality**), a trend since the page opened, **Updated**, **Data type**, **Device** and **Tag key**. **Open trend** opens a trend panel for the last hours; **Open device** opens the device page. | | A device | **Status**, the number of **Tags**, how many have **Bad quality**, **Delivers to** (its outbound targets) and the tags with bad quality. **Open device** opens the device page. | | A group | **Devices online**, **Tags** and **Bad quality** under it, the **Offline devices** and the tags with bad quality. | The trend panel that **Open trend** opens has the ranges **15 min**, **1 h**, **8 h** and **24 h**, the last, average, minimum and maximum value, what happened in the range, and **Open in workspace**, which opens the tag in the [Trend Workspace](https://proxus.io/docs/monitor/trend-workspace). ## The right-click menu Right-click a node to open its menu. **Expand All** and **Collapse All** are available to everyone; the other items only to administrators. *Screenshot: The right-click menu of the Line_1 node with Copy Path, Allow Access to Role, Deny Access for Role, Expand All and Collapse All* 1. **Copy Path** copies the node's path, for example `Meridian/Rotterdam_Beverage_Plant/Filling/Line_1`. Use it as a UNS path in a role's permissions. 2. **Allow Access to Role...** and **Deny Access for Role...** give or take away a role's access to this node and everything under it. Choose the role and select **Apply**. 3. **Expand All** opens every node of the tree. **Collapse All** closes them. ## What's next - [Find a tag and its path](https://proxus.io/docs/organize/find-a-tag) - [Unified Namespace](https://proxus.io/docs/concepts/unified-namespace): how the tree is built from the places of the devices. - [MQTT](https://proxus.io/docs/develop/mqtt): read the same namespace from your own programs. --- # Health Checks > What Health Checks look for in your setup, what each finding means, what to do about it, and how to stop flagging a finding you accept. Source: https://proxus.io/docs/organize/health-checks **Health Checks** look at every configured object (gateways, devices, tags, rules, functions, pipelines, outbound targets and dashboards) and how they connect, and tell you what in the setup is broken, drifting or wasted. It is in **Organize > Health Checks**. Where the [Operations Center](https://proxus.io/docs/monitor/operations-center) tells you what is wrong right now, Health Checks also tell you what follows from it: a device that stopped means a rule that cannot fire and a target that gets nothing. The checks run when you open the page. **Check again** runs them again. The line under the title says how many objects were checked and when. **Open Topology** opens the [Topology](https://proxus.io/docs/monitor/topology) map. ## Findings The **Findings** tab starts with a one-line verdict, then four cards and the list. *Screenshot: Health Checks with the four cards Broken, Needs a look, Waste and Passed, a finding about one gateway carrying everything, and the selected finding's connections on the right* 1. The cards. Select one to show only its findings; select **Passed** to show all of them again. 2. A finding: what is wrong, the object, why it matters, what it affects and **What to do**. 3. **Don't flag again** stops flagging this finding for this object. It is offered for everything except broken findings. 4. The selected finding: the chain of objects from the source to what is affected. For a broken finding it is titled **Where the data stops**, and the broken link is marked. | Card | Meaning | | --- | --- | | **Broken** | Data or automation has stopped. | | **Needs a look** | The edge runs something different from what is configured here, or the setup carries a risk. | | **Waste** | Data is collected or computed and then used by nothing. | | **Passed** | Checks with nothing to report. The list of passed checks is under **… checks passed** at the bottom. | Each finding has a button that opens the object (**Open device**, **Open rule**, **Open gateway** and so on). **Trace this object**, in the panel on the right, opens it in the **Trace an object** tab. ## The checks | Finding | Card | What it means | What to do | | --- | --- | --- | --- | | **Gateway is offline** | Broken | The hub has no connection to the gateway. Devices, rules and functions running on it are stopped. | Check that the gateway host is running and can reach the hub. | | **Device stopped sending data** | Broken | An enabled device sent data before, but nothing arrived within the expected time. | Check the device's network and connection settings, or disable the device if it was retired. | | **Every source is switched off** | Broken | A rule or dashboard reads only from objects that are disabled, so it can no longer produce anything. | Enable one of its sources, or disable it as well. | | **The edge rejected this object** | Broken | A deployed object failed to apply on the edge gateway. | Open the object, read the edge's error, fix it and deploy again. | | **Device has never sent data** | Needs a look | No data has arrived from an enabled device since the hub started. | Check its connection settings and that its gateway can reach it, or disable it until it is installed. | | **Rule reads nothing we can resolve** | Needs a look | No tag, telemetry key or device matches the rule's condition. | Check that the tags or devices in the condition still exist and are spelled as configured. | | **Pipeline is published but runs nowhere** | Needs a look | The pipeline is not assigned to a gateway, or no gateway has received it. | Assign it to a gateway and publish it again, or disable it. | | **Pipeline reads no device** | Needs a look | The pipeline's input matches no device on its gateways. | Check that the devices named in its input still exist and run on its gateways. | | **The edge runs a different version** | Needs a look | What is configured here is not what the edge is running. | Deploy the object, or discard the change if it was a test. | | **Everything runs on one gateway** | Needs a look (**Risk**) | Many rules, functions and targets depend on one gateway; a restart stops them all together. | Plan maintenance around the gateway, or move part of the load to a second gateway. | | **Tags nobody stores or reads** | Waste | Devices poll tags whose data goes to no target or storage, and no rule, function or dashboard reads them. | Send the data to a target, use the tags, or remove them from the profile. | | **Function output goes nowhere** | Waste | A function produces values that are not stored, sent or read. | Use the output, store it, or stop producing it. | ## Findings you accept Some findings are deliberate, for example a test device that is never connected. Select **Don't flag again** on the finding. It moves to **… findings not flagged** at the bottom of the list, where **Flag again** brings it back. This is saved for everyone. ## Trace an object The **Trace an object** tab follows one object through the setup. Type a device, gateway, rule, function, pipeline or target in the search box and choose it. See [See what depends on an object](https://proxus.io/docs/organize/operational-graph#trace-an-object). ## What's next - [See what depends on an object](https://proxus.io/docs/organize/operational-graph) - [Find what stopped](https://proxus.io/docs/monitor/find-what-stopped) - [Troubleshoot automation](https://proxus.io/docs/troubleshoot/automation) --- # See what depends on an object > Before you change, switch off or delete a device, rule or target, see which rules, dashboards and targets depend on it and where its data goes. Source: https://proxus.io/docs/organize/operational-graph At the end of this guide you know which objects depend on the one you want to change, and what stops if you switch it off. Proxus keeps track of how gateways, devices, tags, rules, functions, pipelines, dashboards and targets connect. You can ask from three places. ## Before you start - The object exists and you may open it. - What you see is limited to what your role may read. Objects outside your permissions are counted separately and not listed. ## Ask from the object's page The **Dependencies** action is on the page of a device, a tag, a rule, a function, a dashboard or an outbound target. 1. Open the object, for example **Connect > Devices** and a device. 2. Select **Dependencies**. On the device page it is in the **…** menu at the end of the toolbar. *Screenshot: The overflow menu of the device page opened, with Dependencies at the top* *Screenshot: The Dependencies dialog of MFB_RTM_L1_FILLER showing that one outbound target stops receiving data and one inactive rule is listed separately* 1. The object, its kind and whether the edge runs the configured version (**In sync**). 2. The summary: how many objects a change affects, and in how many kinds of consequence. 3. A group of consequences with its count. Select it to list the objects; select an object to open it. 4. Notes on what is not counted: objects hidden by your permissions, and links that could not be proven. The groups are named by what would happen: | Group | Meaning | | --- | --- | | **Control stops** | Rules and functions lose their input. | | **You go blind** | Dashboards and alerts lose their source. | | **Data stops leaving** | Outbound targets and notification channels stop carrying the data. | | **Also connected downstream** | Reached from here, with no specific failure. | | **Inactive now** | Disabled objects: nothing stops now, but they lose this input when switched back on. | A link is **Proven** when Proxus read it from the configuration, and **Inferred** when it was worked out, for example from a rule's condition. When links could not be proven, the dialog says how many: check those by hand. Select **Close** when you are done. ## The warning before a change When you switch off or delete a device, a tag, a rule, a function, a dashboard or an outbound target, Proxus shows what depends on it before anything happens. This applies to one object on its page and to several selected in a list (**Status > Deactivate Selected**, **Delete**). *Screenshot: The Deactivate anyway? dialog for the rule DOCS_Temperature above 60 °C, listing its dependencies, the acknowledgement box and the Deactivate anyway button* 1. How many objects depend on it and what happens to them. 2. The consequences by group, with counts. 3. Tick the box to confirm you have reviewed the list. 4. **Deactivate anyway** (or **Delete anyway**) is available after you tick the box. **Cancel** leaves everything as it was. Switching off deletes nothing: the dependent objects stop on the next gateway sync and resume when the object is switched on again. Deleting keeps the historical data already written, but leaves the dependent objects pointing at something that no longer exists. ## Trace an object **Organize > Health Checks** has a **Trace an object** tab that shows one object in the middle of its chain. 1. Open **Organize > Health Checks** and select **Trace an object**. 2. Type a device, gateway, rule, function, pipeline or target name in the search box and choose it. *Screenshot: Trace an object for MFB_RTM_L1_FILLER: it depends on the SYSTEM gateway, its device profile and 12 tags, and feeds SYSTEM INTERNAL DB and a switched off rule* 1. The search box. 2. The verdict: whether the object works, and what it feeds. When the data stops, it says where and why. 3. **Depends on**: what the object needs to work, here the gateway, the device profile and its tags. 4. **Feeds**: what uses the object, and what those feed in turn. Switched-off objects are shown faded. Each card shows the object's kind and state. Select **Open device** (or the button for the object's kind) to open it. ## What's next - [Health Checks](https://proxus.io/docs/organize/health-checks): what is broken across the whole setup. - [Topology](https://proxus.io/docs/monitor/topology): the same connections drawn as a map. --- # Application Templates > What an application template holds, the objects it can contain, and what export, import, install, uninstall and delete do. Source: https://proxus.io/docs/organize/app-templates An application template is a package of configured objects (for example a device profile, its devices, the rules that watch them and a dashboard) that can be moved to another hub as one file and installed there. Templates are in **Organize > Application Templates**; the screen's title is **App Templates**. *Screenshot: The App Templates list with one template selected and the New, Export Template, Import Template, Install and Uninstall actions in the toolbar* 1. **New** creates a template. 2. **Export Template** downloads the selected template as a `.json` file. 3. **Import Template** reads a template file and adds it to the list, not installed. 4. **Install** creates the template's objects in this hub. 5. **Uninstall** removes the objects that installing created. ## What a template holds | Field | Meaning | | --- | --- | | **Id** | A short code given when the template is created. It is part of the names of installed objects. | | **Name**, **Description**, **Developer**, **Usage Instructions**, **Image** | What the template is, who made it and how to use it. | | **Date Created** | When the template was created. | | **Installed**, **Installation Date**, **Uninstallation Date** | Whether its objects are in this hub, and when they were added or removed. | | **Objects** | The objects in the template, each with its type and caption. | An object is stored in the template as a copy of its settings at the moment it was added. Changing the original object later does not change the template; remove the object from the template and add it again to take the change. ### Object types When you add an object, **Type** lists the kinds of object a template can hold: **Dashboard**, **Device**, **Device profile**, **Function**, **Notification channel**, **Outbound target**, **Report**, **Role**, **Rule** and **User**. The **Objects** list shows each object's type next to its caption. When you add a device, its device profile (with its tags) is added with it, because a device does not work without it. A device's edge gateway and outbound targets are not copied into the template: they belong to the hub where the template is installed and must exist there. ## Install **Install** asks **Install this template?** and then creates a new copy of every object in the template. The copies are linked to each other the same way as the originals. The originals in the template are not used. - What a copy points at but the template does not hold (edge gateways, rule actions, outbound targets) is not copied. The copy is linked to the same objects in this hub, if they exist here. - A copied device gets its own device token. - A copied object's name gets the template's name and **Id** added, with spaces replaced by underscores. For example, the rule `DOCS_Temperature above 60 °C` from the template `DOCS_Temperature alarm` with Id `1a2b3c4d` becomes `DOCS_Temperature_above_60_°C_DOCS_Temperature_alarm_1a2b3c4d`. This keeps the copies apart from objects that already exist. - Functions are renamed the same way and deployed. - Copies keep their settings, including whether they are active. An inactive rule is installed inactive. - Before installing, Proxus checks the license. If the template would create more objects of a kind than the license allows, nothing is installed and the message says by how many it is over. An installed template cannot be edited; its fields are read-only. ## Uninstall and delete **Uninstall** asks **Uninstall this template?** and deletes the copies that installing created. Functions are undeployed first. The template stays in the list with all its objects, ready to be installed again. > **Warning:** Uninstalling deletes the installed objects, including any changes you made to them after installing. Export or copy anything you want to keep before you uninstall. **Delete** asks **Deleting this template also uninstalls it. Continue?** and removes the template. If it was installed, its objects are removed as described above. ## What's next - [Create and export a template](https://proxus.io/docs/organize/create-an-app-template) - [Import and install a template](https://proxus.io/docs/organize/install-an-app-template) --- # Create and export a template > Collect configured objects such as rules, devices and dashboards into an application template and download it as a file for another hub. Source: https://proxus.io/docs/organize/create-an-app-template At the end of this guide you have an application template that holds the objects you chose, and a `.json` file of it that you can import into another hub. ## Before you start - The objects you want to package exist and work in this hub. The template stores a copy of each object's settings at the moment you add it. - For devices: the edge gateways and outbound targets they use are not part of the template. They must exist in the hub where you install it. - Read [Application Templates](https://proxus.io/docs/organize/app-templates) for what install and uninstall do. ## Create the template 1. Open **Organize > Application Templates** and select **New**. 2. Enter a **Name**, and if you like a **Description**, the **Developer** and **Usage Instructions** for whoever installs it. 3. Select **Save**. The template gets its **Id**. ## Add objects 4. Under **Objects**, select **New**. The **Template Object** dialog opens. 5. In **Type**, choose the type of object. See [Object types](https://proxus.io/docs/organize/app-templates#object-types) for what each name means. 6. A list of the objects of that type opens. Select the object to add. Objects already in the template are not listed. *Screenshot: The Template Object dialog with Rule chosen as the type and the selected rule's name filled in as its caption* 1. **Type**: here **Rule**. 2. **Object Caption**: the chosen object's name, filled in for you. 3. **Save** adds it. **Save and New** adds it and opens the dialog again for the next object. 7. Repeat for every object. When you add a device, its device profile is added with it. 8. Select **Save** on the template. *Screenshot: The template DOCS_Temperature alarm with its name, description and developer, and one rule in the Objects list* 1. The template's **Name**. 2. The objects in the template. 3. **Export Template**. ## Export the template 9. Select **Export Template**. Your browser downloads the file, named after the template and its **Id**, for example `DOCS_Temperature_alarm_1a2b3c4d.json`. Keep the file with your project documents. It holds the objects' settings, including connection settings of devices and target profiles: treat it like a configuration backup. ## What's next - [Import and install a template](https://proxus.io/docs/organize/install-an-app-template) --- # Find a tag and its path > Search the Unified Namespace for a device, read a tag's live value and quality, copy its path and open its trend. Source: https://proxus.io/docs/organize/find-a-tag At the end of this guide you have found a tag in the Unified Namespace, checked its value and quality, copied its path and opened its trend. ## Before you start - The device is set up and sends data. See [Add a device](https://proxus.io/docs/connect/devices/add-a-device). - Your role may read that part of the namespace. ## Find the tag 1. Open **Organize > UNS Explorer**. 2. Type the device name (or part of it) in **Search...** and press Enter. Here: `MFB_RTM_L1_FILLER`. 3. Right-click the top node and choose **Expand All**. 4. Select the tag. The panel on the right shows the tag's value, its quality, when it was updated, its data type, its device and its tag key. **Good** means the device delivered the value without an error. *Screenshot: The tree filtered to MFB_RTM_L1_FILLER and expanded, with the Speed tag selected and its value, quality and details in the panel* 1. The search box. 2. The device, at its place: enterprise **Meridian**, site **Rotterdam_Beverage_Plant**, area **Filling**, cell **Line_1**. 3. The tag **Speed**. 4. The panel with the tag's details and its path. 5. **Open trend**. ## Copy the path 5. In the panel, select **Copy** next to the path. The path is the tag's address in the namespace, such as `Meridian/Rotterdam_Beverage_Plant/Filling/Line_1/MFB_RTM_L1_FILLER/Speed`. Use it where Proxus or another program asks for a UNS path, for example in a role's [UNS permissions](https://proxus.io/docs/administer/uns-permissions) or when subscribing over [MQTT](https://proxus.io/docs/develop/mqtt). ## Open the trend 6. Select **Open trend**. *Screenshot: The trend panel of the Speed tag with range buttons, a one hour chart with a state band, the last, average, minimum and maximum, and the Open in workspace button* 1. The range: **15 min**, **1 h**, **8 h** or **24 h**. 2. **Open in workspace** opens the tag in the Trend Workspace, where you can add other tags, compare periods and export. ## What's next - [Compare tags over time](https://proxus.io/docs/monitor/compare-tags) - [UNS Explorer](https://proxus.io/docs/organize/uns-explorer): every part of the screen. - [Troubleshoot data](https://proxus.io/docs/troubleshoot/data): a tag is missing or does not update. --- # Import and install a template > Bring an application template file into a hub and install it, so its rules, devices, dashboards and other objects are created there. Source: https://proxus.io/docs/organize/install-an-app-template At the end of this guide the objects of a template exist in this hub, as new objects with the template's name in their names. ## Before you start - A template file (`.json`) exported from a hub, or a template already in the list. See [Create and export a template](https://proxus.io/docs/organize/create-an-app-template). - If the template contains devices: the edge gateways and outbound targets they use exist in this hub. - The license has room for the objects the template creates. Install stops if it would go over. ## Import the file Skip this part if the template is already in the list. 1. Open **Organize > Application Templates**. 2. Select **Import Template** and choose the file. The message **Template imported: …** appears and the template is in the list, not yet installed. ## Install 3. Select the template in the list. 4. Select **Install**. *Screenshot: The App Templates list with DOCS_Temperature alarm selected and the Install action in the toolbar* 1. **New** 2. **Export Template** 3. **Import Template** 4. **Install**: available for a template that is not installed. 5. **Uninstall**: available for an installed template. 5. Confirm with **Install**. *Screenshot: The Install template confirmation asking Install this template? with the Install button* The message **Template installed: …** appears and the template is marked **Installed**, with its **Installation Date**. *Screenshot: The template list with DOCS_Temperature alarm ticked as installed and the Uninstall action available* 1. The template, now ticked **Installed**. 2. **Uninstall** is now available. ## Check the result 6. Open the screens of the installed objects, for example **Automate > Rules**. The new objects are named after the original, the template name and its **Id**, such as `DOCS_Temperature_above_60_°C_DOCS_Temperature_alarm_1a2b3c4d`. 7. Check each one before you switch it on: addresses of devices, the gateways they run on, recipients of notification channels. Objects keep the active or inactive state they had when they were added to the template. ## Undo the install Select the template and **Uninstall**, then confirm. The objects the install created are deleted. The template keeps its object list, so you can select **Install** again at any time. ## What's next - [Application Templates](https://proxus.io/docs/organize/app-templates): what install, uninstall and delete do in detail. - [Health Checks](https://proxus.io/docs/organize/health-checks): check the new objects for broken links. --- # Automate > Let Proxus act on your data. Pipelines, rules and functions open alarms, send messages, shape values and call other systems. Source: https://proxus.io/docs/automate **Automate** is where you tell Proxus what to do with the data it reads: open an alarm when a value crosses a limit, warn when a machine goes quiet, clean values before they are stored, send a summary to a database, or run your own code. In the hub, these screens are in the **Automate** menu. ## What you set up here | Screen | What it is for | | --- | --- | | **Pipelines** | A pipeline reacts to data or events and does something with them: alarms, notifications, calculated tags, deliveries to a target, writes to a device. You build it from a goal in plain sentences, or on a canvas of steps. | | **Rules** | A rule watches one kind of event (new data, a device status change, a log entry, gateway metrics) and fires when a condition you write as an expression is true. | | **Rule Actions** | What a rule does when it fires: send a notification through a channel, or forward the matching data to an outbound target. One action can serve many rules. | | **Functions** | Your own C# code, written in the hub and run on the edge gateways you choose. For logic that the other tools cannot express. | ## Which one to use All three run on the edge gateways you choose, next to the machines. - Start with a **pipeline**. It covers most alarm, shaping and delivery tasks, and you can rehearse it on stored data and run it in Shadow before it does anything real. - Use a **rule** when you need a condition over the whole message (its tags, its place, its attributes) or a check on logs and gateway metrics, written as one expression. - Write a **function** when you need code: your own protocol over MQTT or HTTP, a calculation with state, an integration that no pipeline step offers. ## Start here For help choosing, see [Pipelines, rules and functions](https://proxus.io/docs/concepts/pipelines-and-rules). --- # Build a pipeline > Build a pipeline from a goal, rehearse it on stored data, publish it in Shadow, then make it Active. The example alarms on a hot oven zone. Source: https://proxus.io/docs/automate/pipelines At the end of this guide, a pipeline watches the zone 1 temperature of a tunnel oven and opens a Critical alarm when it reaches 200 °C. You build it from a goal in plain sentences, check what it would have done over the last day, run it in Shadow on the gateway, and then make it Active. The example uses the demo device `MFB_LYS_TUNNEL_OVEN` in Lyon Foods Plant. Use your own device and tag in its place. For what pipelines are and how publishing works, see [How pipelines work](https://proxus.io/docs/automate/pipeline-concepts). ## Before you start You need: - A device that sends values, on an edge gateway that shows **Connected**. See [Add a device](https://proxus.io/docs/connect/devices/add-a-device). - The tag you want to watch (here `Zone1Temp`) and the limit you want to alarm on. - A user role that may create and publish pipelines. ## Step 1: Start from a goal 1. Go to **Automate > Pipelines** and select **New** (1). *Screenshot: The pipeline list with the New button marked in the toolbar* 2. The new pipeline asks **What should this pipeline do?** Select **Alarm when a value crosses a limit** (1). Type in **Search goals** to find a goal by name. *Screenshot: The goal gallery with the goal Alarm when a value crosses a limit marked* The goals are grouped by what they do: | Group | Goals | | --- | --- | | Watch and alert | Alarm when a value crosses a limit, Warn when data stops, Alarm when a device disconnects, Alarm on a combination, Spot unusual behaviour | | Watch the gateways | Alarm when a gateway stops, Alarm on high gateway load, Notify on error logs | | Shape the data | Clean and convert data, Mark out-of-range values, Drop data you do not need | | Calculate and enrich | Compute a new value, Store a smoothed value, Hourly, shift or daily summaries, Add context to data | | Connect and schedule | Send changes to a target, Run a scheduled task, Write to a device, Pull data from an API, Send data to an API | Under each goal it says whether the pipeline **Reacts to stored data** or **Changes data before it is stored**. To build from nothing, select **Start from an empty story** at the bottom. ## Step 2: Fill in the story The **Build** tab shows the pipeline as a story that reads like a sentence. Type a **Name** at the top, for example `Oven zone 1 temperature high`, then fill in the story from top to bottom. *Screenshot: The story builder with gateway SYSTEM, device MFB_LYS_TUNNEL_OVEN, tag Zone1Temp, a limit of 200 back to 190 and a Critical alarm* 1. **When** (1) is what starts the pipeline. This goal uses **A new value arrives**. 2. **For** (2) decides where it runs and what it watches: - **Runs on**: the gateways that run the pipeline. Choose these first; the other lists offer what those gateways have. - **Sites**, **Devices**: leave empty for all, or narrow it down. - **Tags**: the tags the pipeline reads, here `Zone1Temp`. 3. **Steps** (3): set the limit. "continue when `Zone1Temp` reaches `200`, until it is back to `190` or less". The second value is the dead band: the alarm stays open until the value has dropped to it, so a value that hovers around 200 does not open and close the alarm again and again. 4. **Then** (4): choose the severity (**Critical**) and type the alarm message. 5. **If it ran now** (5) applies the story to the latest value of each device and tells you what would happen. With **Live** ticked it refreshes by itself. Nothing is sent, written or opened. **Otherwise** is what happens when the value is back to normal; here nothing happens. Use **Add step** for more steps, for example **Notify** to send a message through a notification channel. The **Checks** panel lists what is still missing ("Choose the gateways it runs on.", "Give the pipeline a name above."). When it says the story is complete, go on. ## Step 3: Rehearse on stored data Select **Review & publish** at the top of the story. *Screenshot: The review page with a rehearsal over 24 hours of the oven's history and the live check below it* 1. **Rehearse on history** (1): pick **24 hours** or **7 days** and select **Rehearse**. The draft runs over the stored values of that period, step by step as the gateway would have run it, and counts per device the messages, alarms and other actions it would have produced. Nothing is sent. 2. **If it ran now** (2) shows the result for the latest values again. If the rehearsal opens far more alarms than you expect, go back to **Build** and change the limit. ## Step 4: Validate and publish in Shadow Further down the review page is the **Publish** card. *Screenshot: The Publish card after validating and publishing in Shadow, with the Validate and Publish in Shadow buttons* 1. Select **Validate** (1). The draft is checked against every gateway it runs on. A message says "Pipeline definition is valid.", or names what is wrong. 2. Select **Publish in Shadow** (2). Both buttons save the pipeline first. In **Shadow**, the gateway runs the pipeline on real data and records what it would do, without changing data, opening alarms or writing to devices. Each publish creates a numbered revision. ## Step 5: Check the deployment *Screenshot: The Deployments tab showing the SYSTEM gateway as Healthy and Online with its catalog synced* 1. **Publish Active** in the toolbar, for step 6. 2. The **Deployments** tab. Open it. Each gateway in **Runs on** has a row. **Runtime** shows **Online** when the gateway runs the pipeline and reports back. **Coverage** tells you how many devices it could bind, and **Last error** shows the reason when a gateway could not apply it. The **Revisions** tab lists each published revision with its mode, the time and who published it. *Screenshot: The Revisions tab with revision r1 in Shadow mode marked as Current* ## Step 6: Make it Active When Shadow has looked right for a while, select **Publish Active** in the toolbar and confirm. From now on the pipeline opens real alarms; they appear in [Alerts](https://proxus.io/docs/monitor/alerts), one per device. > **Warning:** In Active mode, steps that call an API, write to a device or send to an outbound target do real work. The confirmation warns that HTTP receivers may not ignore repeated requests and that device writes are not guaranteed to happen exactly once. API calls, device writes and sends to outbound targets also run only on gateways where `EffectsEnabled` is switched on in the `[Flows]` section of the configuration file; see [How pipelines work](https://proxus.io/docs/automate/pipeline-concepts#external-actions). ## Change or stop a pipeline - **Change it**: edit the story or the canvas, then publish again. The running revision stays as it is until you publish. If nothing changed, publishing says "The active revision already matches this definition." - **Go back**: when there are earlier revisions, **Rollback** in the toolbar lists the earlier revisions ("Revision 2 - Shadow") and publishes the one you pick again. - **Stop it**: **Disable** removes it from all its gateways. A disabled pipeline can be **Archive**d. - **Delete it**: **Delete draft** is only offered while the pipeline has never been published. - **Many at once**: in the pipeline list, select several rows and use **Pipeline lifecycle** to publish them in Shadow, publish them Active or disable them. ## Work on the canvas The **Canvas** tab shows the same pipeline as connected steps. Use it for what the story cannot say, such as several branches. *Screenshot: The canvas with the node list on the left, four connected nodes and the inspector of the Band node on the right* 1. The bar at the top shows the pipeline **Type**, **Order**, **On error** and **Runs on**. 2. **Nodes**: drag a node onto the canvas, or select it and press Enter. Type in **Find a node** to search. 3. Drag from an output port to an input port to connect two nodes. Select a node to configure it. 4. The inspector on the right shows the selected node's settings. The canvas will not connect a node to itself or make a loop. If you change the shape of the pipeline on the canvas, the **Build** tab shows "Changed in the canvas" and offers **Rebuild from story**. Every node is described in [Pipeline nodes](https://proxus.io/docs/reference/pipeline-nodes). ## Test with your own sample The **Sandbox** tab runs the draft on a sample you write, without any external effect. *Screenshot: The Sandbox tab with the Tests for this draft panel and the custom sample section opened* - **Tests for this draft** runs generated scenarios with **Run all scenarios**, where the pipeline type allows it. - **Advanced · Custom sample and execution trace**: choose the gateway, an example device and the event, edit the values of the sample, and select **Run sample**. The result shows whether the pipeline matched, the path it took and the effects it suppressed. **Load latest capture** fills the sample from what a published pipeline has just seen on the gateway. To see live samples from a published pipeline, add the step **Keep a sample for Trace** and open the **Trace** tab. ## What's next - [How pipelines work](https://proxus.io/docs/automate/pipeline-concepts): types, Shadow and Active, effects and limits. - [Pipeline nodes](https://proxus.io/docs/reference/pipeline-nodes): every node and its settings. - [Alerts](https://proxus.io/docs/monitor/alerts): where the alarms appear. - [Automation troubleshooting](https://proxus.io/docs/troubleshoot/automation). --- # How pipelines work > The two kinds of pipeline, story and canvas, drafts and revisions, Shadow and Active, external actions and the limits a pipeline must stay within. Source: https://proxus.io/docs/automate/pipeline-concepts A pipeline is a small program of connected steps that an edge gateway runs on the data it reads. You design it in the hub; the gateway runs it next to the machines. This page explains the ideas behind the [pipeline editor](https://proxus.io/docs/automate/pipelines). ## Two kinds of pipeline Every pipeline has a type. The goal you start from sets it, and the editor says which one it is. | Type | On screen | What it does | | --- | --- | --- | | **Automation** | Reacts to stored data | Starts from an event: new tag values, a value change, no data for a while, a device or gateway status change, a log entry, gateway load figures, or a schedule. It adds alarms, notifications, calculated tags, deliveries or device writes. The stored data itself is not changed. | | **Transport Pipeline** | Changes data before it is stored | Runs on every message a device sends, before it is stored or sent to outbound targets. It converts, renames, sets units and quality, adds context, drops or sets aside values. What it outputs is what gets stored. | A Transport Pipeline has exactly one start, **Transport Input**. An Automation pipeline has between one and eight sources. ### Order of Transport Pipelines When several Transport Pipelines run on the same gateway, a message passes through them in turn. They are sorted by **Stage** (**Normalize**, **Enrich**, **Quality**, **Route**, in that order) and then by **Order** within a stage. **Overwrite** allows a later pipeline to overwrite a field an earlier one wrote. **On error** decides what happens to a message when a step fails: - **Pass Original**: the message continues as it was before this pipeline. - **Drop**: the message is dropped. - **Quarantine**: the message is set aside for inspection. ## Story and canvas The same pipeline can be edited in two ways: - **Build** shows it as a story in five parts: **When** (what starts it), **For** (gateways, sites, devices, tags), **Steps**, **Then** (what it does), **Otherwise** (what it does when the condition does not hold). Behind the story are the same connected steps the canvas shows. - **Canvas** shows those connected steps (nodes) and lets you build what the story cannot say, such as several branches. Changing values on the canvas is read back into the story. If you change the shape of the pipeline on the canvas, the story no longer matches it; the **Build** tab then offers **Open canvas** or **Rebuild from story**. A pipeline made on the canvas can be replaced with a story with **Replace with a story**. Every node is listed in [Pipeline nodes](https://proxus.io/docs/reference/pipeline-nodes). ## Draft, revision, deployment - The **draft** is what you edit. **Save** keeps it, but the gateways keep running what was published before. - **Validate** checks the draft against each gateway in **Runs on**: the steps must form a valid graph (no loops, every step reachable from a source, settings complete), and the devices and tags it needs are looked up on that gateway. - **Publish Shadow** or **Publish Active** makes a numbered **revision**, a copy that never changes, and sends it to every gateway in **Runs on**. Publishing an unchanged draft in the same mode makes no new revision. - Each gateway then has a **deployment** of that revision. The **Deployments** tab shows, per gateway, whether it was applied, how many devices it could bind (**Coverage**), whether the gateway still reports (**Runtime**) and the last error. - **Rollback** publishes an earlier revision again. **Disable** removes the pipeline from all gateways. Only a disabled pipeline can be archived, and only a pipeline that was never published can be deleted (**Delete draft**). A gateway removed from **Runs on** is told to stop the pipeline at the next publish. ## Shadow and Active | Mode | What runs | What happens | | --- | --- | --- | | **Shadow** | The whole pipeline, on real data, on the gateway | Nothing is changed. Alarms, messages, deliveries and device writes are counted as "would" actions only. | | **Active** | The whole pipeline | Alarms are opened and closed, messages sent, values stored, and external actions done. | Publish in Shadow first and look at the **Deployments** and **Trace** tabs for a while; then publish Active. The pipeline list shows each pipeline's mode in the **Published** column. ## Ways to check a draft before publishing | Tool | Where | What it uses | | --- | --- | --- | | **If it ran now** | Build and Review | The latest value of each device, every few seconds with **Live**. | | **Rehearse on history** | Review & publish | The stored values of the last **24 hours** or **7 days**, up to 25,000 values per device. | | **Sandbox** | Sandbox tab | Generated scenarios, or a sample you write or load from the gateway. | | **Trace** | Trace tab | Live samples from a published pipeline that has a **Keep a sample for Trace** step. | None of them sends, writes or opens anything. ## External actions Three kinds of step act outside Proxus: **Call an API** and **Send to an API**, **Write to a device**, and **Send to a target** (except **Store as tag**, which keeps the result in Proxus). In Active mode they run only on gateways where the configuration file allows it: ```toml [Flows] EffectsEnabled = false ``` With `EffectsEnabled = false` (the default), such steps are refused on that gateway and the pipeline reports "External actions disabled". Alarms, notifications and **Store as tag** are not affected. In Shadow, external actions never run. Set the key on each gateway that should do them; see [Configuration keys](https://proxus.io/docs/reference/configuration). Device writes stay within the minimum and maximum you set on the step, and can only target a tag that is not read-only and is a number or a true/false value. ## Limits A pipeline is checked against these limits when you validate it: | Limit | Value | | --- | --- | | Name | 1 to 120 characters | | Nodes per pipeline | 1 to 128 | | Connections per pipeline | 256 | | Pipeline definition size | 256 KB | | Sources in an Automation pipeline | 1 to 8 | | Branches from one node | 16 | | Tags in one message | 1024 | | Values in a window (moving average and similar) | 1024 | | Formula length | 1024 characters | | Memory for steps that keep state (windows, dead bands, summaries) | 8 MB per pipeline, 64 MB per gateway | | Pipelines per gateway | 256 | ## What's next - [Build a pipeline](https://proxus.io/docs/automate/pipelines) - [Pipeline nodes](https://proxus.io/docs/reference/pipeline-nodes) - [Pipelines, rules and functions](https://proxus.io/docs/concepts/pipelines-and-rules) --- # Create a rule > Write a rule that watches data, device status, logs or gateway metrics, and raises an alert and runs actions each time its condition matches. Source: https://proxus.io/docs/automate/rules At the end of this guide, a rule raises an alert when zone 1 of a tunnel oven has been above 200 °C for five minutes, at most once every five minutes. You build the condition as a sentence, check what it would have done over the last 24 hours, choose the gateways that check it, and turn it on. A rule checks each message as it arrives. Per device it remembers only two things: how long the condition has held, for the [wait](#wait-before-the-alarm), and whether its alarm is open, so the alarm can [close by itself](#close-the-alarm) when the value is back to normal. For logic that spans several messages or devices, use a [pipeline](https://proxus.io/docs/automate/pipelines). ## Before you start You need: - A device that sends values, on a connected edge gateway. - The tag name you want to check (here `Zone1Temp`) and the device name (here `MFB_LYS_TUNNEL_OVEN`). - A user role that may create rules. ## Step 1: Create the rule Go to **Automate > Rules** and select **New** (1). *Screenshot: The rule list with the New button marked in the toolbar and the demo rules below it* The list shows each rule's **Status**, what it **Watches**, its **Condition**, how many **Open Alarms** it has, when it **Last Fired** and where it **Runs On**. The demo rules, such as **Temperature Threshold Alert**, are good examples to open and read. ## Step 2: Fill in the form *Screenshot: The rule form with the name, the event On Data Received, a trigger limit of 1 and a throttle period of five minutes, and below it the condition editor: the device, Zone1Temp above 200, the wait, and the Now, Last 24 hours and Check panels* 1. **Name**: a unique name, for example `Oven zone 1 above 200`. 2. **Event**: what the rule watches. | Event | The rule checks | | --- | --- | | **On Data Received** | Every message of tag values a device sends. | | **On Status Changed** | A device connecting or disconnecting. | | **On Log Received** | Every log entry of the gateway. | | **On Metrics Received** | The read statistics of each device (requests, errors, response time, data quality). | Changing the event clears the condition, because each event has its own fields. 3. **Trigger Limit**: how many times the rule may act within one throttle period. Here `1`. 4. **Throttle Period**: the length of that period, here five minutes (`00:05:00`). See [Throttling](#throttling). 5. Build the **Condition** as a sentence: - **Where**: **Device** and `MFB_LYS_TUNNEL_OVEN`. **Site** or **Area** checks every device there; **Any device** checks all of them. - **When**: the tag `Zone1Temp`, **above**, `200`. The tag list shows each tag's unit and how many devices in scope have it; under each comparison you see the tag's lowest, average and highest value of the last 24 hours and its value now, so you can pick a sensible limit. **Add comparison** adds another one; choose whether all of them or any one must hold. **Between** and **outside** take a lower and an upper limit. - Or type the condition in your own words in the box at the top (for example *Tunnel oven zone 1 above 200 degrees for 5 minutes*) and press Enter or select **Turn into a condition**. The Copilot fills in the sentence and the wait from your devices and tags; when the sentence describes a lost connection, a log entry or read errors, it switches the rule's event too. Check the result before saving; **Undo** brings back the condition, the wait and the event you had. When the sentence names a device or tag that does not exist, matches more than one device, or is not a condition, the Copilot says why and leaves the condition as it was. This needs a [Copilot provider](https://proxus.io/docs/administer/copilot-settings). - A new rule offers templates: **Above a limit**, **Outside a range**, **Connection lost**, **Error log** and **Read errors**. 6. **Wait before the alarm**: **5 minutes** (`300` seconds). See [Wait before the alarm](#wait-before-the-alarm). 7. **Close the alarm**: **With a margin**, **5** °C: the alarm closes once zone 1 is back below 195 °C. See [Close the alarm](#close-the-alarm). **In words** repeats the condition as a sentence; check that it says what you mean. **Expression** shows the text the gateway runs, and switches to typing it when you need something the sentence cannot say. All fields and operators are in [Rule expressions](https://proxus.io/docs/automate/rule-expressions). Beside the condition, three panels check it before you save: - **Now**: whether the condition holds on the devices in scope with their latest values. - **Last 24 hours, had this rule run**: the condition and the wait replayed over the stored history: a chart of the first tag with the limit and the times the alarm would have been on, the number of alarms, their total and longest time, and a hint when it would fire too often or never. History is replayed in 15-second steps, so a spike shorter than that can be missed; only devices whose data is stored (sent to **SYSTEM INTERNAL DB**) have history. - **Check**: whether the gateway can compile the condition, what is still missing, and where the rule runs. Leave **Engine** on **Criteria Expression**. **Trigger** always shows **Real-Time**: rules are checked as each event arrives. ## Step 3: Choose the gateways The **Gateways** tab below the form lists the gateways that check the rule. A new rule starts with **SYSTEM**, the hub's own gateway. Add the gateway that reads your device. A rule only sees the data of the gateways it runs on. ## Step 4: Decide what happens Each match, within the throttle, creates or updates an alert in [Alerts](https://proxus.io/docs/monitor/alerts): - If the rule's latest alert is still **New**, its count goes up and its time is updated. - If that alert was acknowledged, resolved or ignored, a new alert is created. To get a message or forward the data as well, add an action on the **Actions** tab. See [Add a rule action](https://proxus.io/docs/automate/rule-actions). Tick **Enable UI Alerts** to also show a pop-up in the hub for each alert, with a **View Details** button. ## Step 5: Turn it on 1. Tick **Active**. 2. Select **Save**. The rule is sent to its gateways and starts checking at once. Clear **Active** and save to stop it. > **Note:** While a rule is active, its settings are locked. To change the condition, the throttle or the gateways, clear **Active** and save first, make the change, then turn it on again. To turn several rules on or off at once, select them in the list and use **Status** > **Activate Selected** or **Deactivate Selected**. ## Wait before the alarm **Wait before the alarm** fires the rule only when its condition has held on the same device, without a break, for that long: a short spike above the limit raises nothing. A message that does not match starts the wait over, and so does a silence longer than the wait. **At once** (`0`) fires on the first match, as rules did before. Status and metric rules wait the same way; log rules always fire at once. The wait needs gateways of version 2.0.0 or later; an older gateway ignores it and fires at once. ## Close the alarm **Close the alarm** decides who resolves the alarm a rule opens: - **By hand**: someone resolves it in **Alerts**, as before. - **When the condition ends**: the gateway resolves it by itself on the first message where the condition no longer holds on that device. - **With a margin**: the value must come back past the limit by the margin before the alarm closes. With *above 200* and a margin of 5 the alarm opens above 200 and closes below 195, so a value hovering around 200 does not open and close it over and over. Between and Outside conditions move both limits; a margin is offered only for numeric limits. While nobody has taken the alarm, each new firing on that device counts on it; once it has closed, the next time the condition holds opens a new alarm. The resolved alarm keeps the time it closed. **Last 24 hours, had this rule run** replays the closing too, and draws the closing limit as a dashed line, so you can choose a margin that keeps the alarm count low. An alarm left open while a gateway restarts closes the first time its value is back to normal. Log rules have no closing: a log entry is a moment. Closing needs gateways of version 2.0.0 or later. ## Throttling **Trigger Limit** and **Throttle Period** work as a counting window per rule: 1. The first match starts a window of **Throttle Period** and acts. 2. Further matches act until **Trigger Limit** is reached. 3. Matches after that are skipped until the period has passed. The gateway writes one warning to the log ("limit reached for rule ...") per window. 4. The first match after the period starts a new window. Alerts and notifications share one counter; forwarding to outbound targets has its own. Set **Trigger Limit** or **Throttle Period** to `0` for no limit. A new rule starts with one action per minute. > **Warning:** A rule on **On Log Received** whose action writes a log entry can fire itself again and again. Keep its condition narrow (for example a **ReasonCode**) and keep a throttle. ## Find out why a rule did or did not fire - The top of the rule shows **Open alarms**, **Last fired**, the number of **Actions** and the **Throttle**. - The **Alerts** tab lists the alerts this rule raised. - **Logs** in the toolbar opens the gateway log entries for this rule, for example a condition that could not be read or a throttle that was reached. A condition with a typing error never matches; the log then says the criteria could not be compiled. ## Spot unusual values Set **Engine** to **Anomaly Detection** to fire on values that do not fit a tag's recent pattern instead of a fixed limit. It only works with **On Data Received**. The condition still decides which messages are looked at; if it names one tag (`[Payload][Key = 'Zone1Temp']`), only that tag is analysed. The **Anomaly Detection** tab lists the methods. Switch on the ones you want; the first that fires wins. | Method | Fires when | Settings (default) | | --- | --- | --- | | **Use Gap** | No new value for longer than expected | **Expected Interval Seconds** (60), **Gap Factor Threshold** (1.8) | | **Use ZScore** | A value is far from the average, measured in standard deviations | **ZScore Threshold** (3.0) | | **Use Rolling Median** | A value is far from the median | **Rolling Median Multiplier** (1.2) | | **Use Rate Of Change** | A value jumps by more than a share of the previous one | **Rate Of Change Threshold** (0.25) | | **Use Ema** | A value moves away from its smoothed average | **Ema Alpha** (0.1), **Ema Difference Multiplier** (0.01) | | **Use Iqr** | A value is outside the usual range of the middle half of values | **Iqr Multiplier** (1.5) | | **Use Moving Average** | A value is far from the moving average | **Moving Average Threshold** (1.5) | | **Use Drift** | Several values in a row stay on one side of the average | **Drift Run Length** (3), **Drift Threshold Percent** (1.0) | | **Use Flatline** | The value stops moving | **Flatline Window** (6), **Flatline Tolerance Percent** (0.25) | **Analysis Window** (1000) is how many past values are kept per tag. Apart from **Use Gap**, no method fires until that many values have arrived, so a large window takes a while to start. The history is kept per tag name, so devices with the same tag name share it; narrow the condition to one device when that matters. ## What's next - [Rule expressions](https://proxus.io/docs/automate/rule-expressions): fields, operators and examples. - [Add a rule action](https://proxus.io/docs/automate/rule-actions): send a message or forward data. - [Alerts](https://proxus.io/docs/monitor/alerts): acknowledge and resolve what rules raise. --- # Rule expressions > The fields, operators and functions you can use in a rule condition for each event, with examples that are tested against the rule engine. Source: https://proxus.io/docs/automate/rule-expressions A rule's condition is one expression. The gateway checks it against each event of the kind the rule watches (**Event** on the rule) and fires when it is true. You build it as a sentence in the rule's condition editor, or type it under **Expression**; both give the same expression, and a typed expression the sentence can say switches back to it. See [Create a rule](https://proxus.io/docs/automate/rules). The fields below are what the gateway hands to the rule for each event. Names are case-sensitive; text values are written in single quotes. ## Operators and functions - Compare: `=`, `==`, `<>`, `!=`, `<`, `<=`, `>`, `>=`. - Combine: `AND` (or `&&`), `OR` (or `||`), `NOT`, and brackets `( )`. - Arithmetic: `+`, `-`, `*`, `/`. - Functions used in the examples below: `Contains(Field, 'text')`, `Abs(x)`, `ToDouble(text)`. - Inside a list: `[List][condition]` is true when at least one item of the list matches the condition. ## On Data Received Each message holds the values one device sent at one moment. | Field | What it is | | --- | --- | | `Topic` | The device ID. | | `[Payload]` | The list of tag values in the message. Each item has `Key` (the tag name), `NumericValue` (the value as a number), `Value` (the value as text), `PreviousValue` (the previous value as text), `Unit`, `Type`, `Quality` (`Good`, `Bad`, `Uncertain`), `Time` and `PreviousValueTime`. | | `[MetaData]` | Where the device is. Items have `Key` and `Value`; keys are `DeviceId`, `DeviceName`, `Enterprise`, `Site`, `Area`, `ProcessCell`, `EquipmentModule`. | | `[Attributes]` | The device's own attributes, as `Key` and `Value`. | A tag is always checked inside `[Payload][...]`, with its name and its condition in the same brackets. Compare numbers with `NumericValue`, not `Value`: `Value` is text. A message only contains the tags the device read at that moment, so a condition on two tags of the same message needs both in it. ```text [Payload][Key = 'Temperature' AND NumericValue > 28] ``` A tag outside a band: ```text [Payload][Key = 'Voltage' AND (NumericValue < 215 OR NumericValue > 245)] ``` One device only, by name: ```text [MetaData][Key = 'DeviceName' AND Value = 'MFB_LYS_TUNNEL_OVEN'] AND [Payload][Key = 'Zone1Temp' AND NumericValue > 200] ``` All devices whose name contains a word: ```text [MetaData][Key = 'DeviceName' AND Contains(Value, 'PowerGenerator')] AND [Payload][Key = 'Temperature' AND NumericValue > 85] ``` A jump of more than 5 since the previous reading: ```text [Payload][Key = 'Pressure' AND Abs(NumericValue - ToDouble(PreviousValue)) > 5] ``` A rise of more than 10 % since the previous reading: ```text [Payload][Key = 'FillRate' AND ToDouble(PreviousValue) <> 0 AND (NumericValue - ToDouble(PreviousValue)) / ToDouble(PreviousValue) > 0.10] ``` Several conditions, one of them negated: ```text [Topic] = 'Device123' AND [Payload][Key = 'Pressure' AND NumericValue > 100] AND NOT [Payload][Key = 'Temperature' AND NumericValue < 25] ``` Two device attributes: ```text [Attributes][Key = 'Location' AND Value = 'FactoryA'] AND [Attributes][Key = 'Priority' AND Value = 'High'] ``` ## On Status Changed | Field | What it is | | --- | --- | | `DeviceId`, `DeviceName` | The device. | | `CurrentConnectionStatus` | `Unknown`, `Connected` or `Disconnected` (or `0`, `1`, `2`). | | `PreviousConnectionStatus` | The status before this change. | | `ConnectionDuration` | How long the previous status lasted, in seconds. | ```text CurrentConnectionStatus = 'Disconnected' ``` A device that came back after less than a minute away: ```text CurrentConnectionStatus = 'Connected' AND PreviousConnectionStatus = 'Disconnected' AND ConnectionDuration < 60 ``` ## On Log Received | Field | What it is | | --- | --- | | `Time`, `Level`, `Source`, `Category`, `Message` | When, how serious (for example `Warning`, `Error`, `Critical`), which gateway, which part of it, and the text. | | `ReasonCode` | A stable code for the kind of event, where the product sets one. Prefer it to matching `Message` text. | | `EventId`, `CorrelationId`, `Operation`, `EntityType`, `EntityId`, `Fingerprint`, `OccurrenceCount`, `Diagnostic` | More detail, where present. | ```text Level = 'Critical' OR Level = 'Error' ``` ```text Level == 'Error' && Contains(Category, 'FieldbusActor') ``` Log entries written by the rule engine and by notifications themselves are not passed to rules. ## On Metrics Received The read statistics of one device, sent after each read cycle. | Field | What it is | | --- | --- | | `Device` | The device. | | `TotalRequests`, `SuccessfulRequests`, `FailedRequests`, `ResponseCount` | Read requests so far. | | `ReadErrorCount`, `ConnectionErrorCount`, `ReadErrorPercentage` | Errors so far, and the share of failed reads in percent. | | `AverageResponseTime` | Average response time of the device. | | `LastCommunicationTime`, `LastDataReceivedTime` | When the device last answered and last sent data. | | `TotalDataReceived`, `ProcessedDataCount`, `SleepModeTransitionCount` | Counters. | | `DataAccuracy`, `DataCompleteness`, `DataFreshness`, `DataIntegrity`, `DataConsistency` | Data quality scores. | ```text ReadErrorPercentage > 10 ``` ```text FailedRequests > 100 && ReadErrorPercentage > 20 ``` ```text DataAccuracy < 80 ``` ## Common mistakes | Written | Problem | Write instead | | --- | --- | --- | | `[Temperature] > 80` | Tags are not fields of the message. | `[Payload][Key = 'Temperature' AND NumericValue > 80]` | | `[Payload][Key = 'Temperature' AND Value > 80]` | `Value` is text. | `NumericValue > 80` | | `[Payload][Key = 'A'] AND [Payload][NumericValue > 5]` | The two parts may match two different tags. | Put name and condition in one bracket: `[Payload][Key = 'A' AND NumericValue > 5]` | An expression the gateway cannot read never matches. The rule's **Logs** then show that the criteria could not be compiled. ## What's next - [Create a rule](https://proxus.io/docs/automate/rules): use the expression in an alarm rule. - [Add a rule action](https://proxus.io/docs/automate/rule-actions): send a notification or forward data when the rule fires. - [Troubleshoot automation](https://proxus.io/docs/troubleshoot/automation): rules that do not match or do not fire. --- # Add a rule action > Make a rule send a notification through a channel or forward the matching data to an outbound target, and reuse the same action on many rules. Source: https://proxus.io/docs/automate/rule-actions At the end of this guide, the oven rule from [Create a rule](https://proxus.io/docs/automate/rules) sends a Microsoft Teams message each time it fires. A rule action is defined once and can be linked to as many rules as you like. ## Before you start You need: - A rule. See [Create a rule](https://proxus.io/docs/automate/rules). - For a notification: a notification channel (email, Teams, Slack, SMS and others). See [Notification channels](https://proxus.io/docs/connect/notification-channels). - For forwarding data: an outbound target. See [Outbound targets](https://proxus.io/docs/connect/outbound-targets). ## The two kinds of action | Action Type | What it does when the rule fires | | --- | --- | | **Notification Action** | Sends a message through the chosen **Notification Channel**. The message is written by Proxus: it names the rule, the time and why it fired, and quotes the rule's condition. | | **Trigger Outbound Target** | Forwards the message that matched (all its tag values and its place) to the chosen **Outbound Target**. Works only for rules on **On Data Received**. | An action runs each time its rule fires, within the rule's throttle. Nothing runs when the condition stops being true. ## Step 1: Create the action 1. Go to **Automate > Rule Actions** and select **New**. 2. Fill in the form. *Screenshot: The rule action form with the name DOCS_Notify oven team, the type Notification Action and the channel Microsoft Teams* 1. **Name**: a unique name that says what it does, for example `Notify oven team`. 2. **Action Type**: **Notification Action**. 3. **Notification Channel**: the channel to send through, here **Microsoft Teams**. For **Trigger Outbound Target** this field is **Outbound Target** instead. Select **Save**. > **Note:** The **Template** field is not used for the message today: whatever you type there, the channel receives the message Proxus writes for the rule. Leave it empty. ## Step 2: Link it to the rule 1. Open the rule in **Automate > Rules**. 2. Open the **Actions** tab (1) below the form. 3. Select **Link** (2) and select the action in the list. It is added to the rule. 4. Select **Save**. *Screenshot: The Actions tab of a rule with the Link button and the linked action DOCS_Notify oven team* **New** on the same tab creates an action and links it in one go. **Unlink** removes the action from this rule only. The **Rules** column tells you how many rules use an action. If the rule is active, its settings are locked: clear **Active**, save, link the action, then turn it on again. ## When a message does not arrive - A failed delivery is tried again a few times, with growing pauses, before it is given up. - **Logs** in the rule action's toolbar opens the log entries of the notification sender, with the reason a message failed (a wrong address or token on the channel, for example). - Check that the rule fired: its **Alerts** tab and **Last fired** show it. - Check the rule's **Trigger Limit** and **Throttle Period**: matches over the limit run no action. ## What's next - [Create a rule](https://proxus.io/docs/automate/rules) - [Notification channels](https://proxus.io/docs/connect/notification-channels) - [Automation troubleshooting](https://proxus.io/docs/troubleshoot/automation) --- # Write a function > Write a C# function in the hub, build it, deploy it to edge gateways and read its log entries. Start from a template or from your own code. Source: https://proxus.io/docs/automate/functions At the end of this guide, a small C# function runs on the hub's gateway. It reads every message of a tunnel oven and writes a warning to the log, at most once a minute, while zone 1 is above 180 °C. The same steps apply to any function you write. A function is a C# class that the gateway runs next to its devices. Use one when a [pipeline](https://proxus.io/docs/automate/pipelines) or a [rule](https://proxus.io/docs/automate/rules) cannot express what you need. The classes and helpers you can use are described in [Functions SDK](https://proxus.io/docs/develop/functions-sdk). ## Before you start You need: - An edge gateway that shows **Connected**. - Some C#. The editor completes code and marks errors as you type. - A user role that may create and deploy functions. ## Step 1: Create the function Go to **Automate > Functions** and select **New** (1). *Screenshot: The function list with the New button marked in the toolbar* The new function opens with an empty editor and a **Configuration** section below it. ## Step 2: Start from a template or write the code To start from an example, open the toolbar's **More items** menu (**...**) and select **Templates**. Select one template and then **Select**. The editor content is replaced by the template. *Screenshot: The Function Template list with nine templates and their descriptions* | Template (listed as `Product..cs`) | What it does | | --- | --- | | DerivedMetricsFunction | Adds calculated values to incoming device data. | | DeviceHealthMonitorFunction | Marks devices as healthy or stale from the time of their last values. | | HistoricalJsonImportFunction | Imports historical values from JSON with their own timestamps. | | HttpJsonPollingFunction | Polls a REST endpoint and saves chosen JSON fields as values. | | MqttJsonIngestionFunction | Subscribes to an MQTT JSON topic and saves its properties as values. | | OeeTrackerFunction | Calculates OEE figures from common production counters. | | PayloadNormalizerFunction | Renames values and converts units before data is stored. | | SqlPollingIngestionFunction | Polls a SQL source and saves the result as values. | | ThresholdAlarmFunction | Raises threshold alarms with a cooldown and a dead band. | Each template gets a short random suffix on its class name, so you can use the same template twice. For this guide, paste this code into the editor instead: ```csharp using System; using Proxus.Common; using Proxus.Common.Messages; using Proxus.SDK.BaseFunctions; namespace Plant { public sealed class OvenZoneWatch(object _, object __, object ___) : FunctionBase(_, __, ___) { private const string Device = "MFB_LYS_TUNNEL_OVEN"; private const double Limit = 180; private static readonly TimeSpan Quiet = TimeSpan.FromMinutes(1); private DateTime _lastWarning = DateTime.MinValue; protected override void OnStarted() { // Receive every message of tag values the gateway reads. Subscriptions?.Add(new SubscriptionContext { Type = typeof(TransportData), Topics = ["*"] }); base.OnStarted(); } protected override void OnMessageReceive(FunctionContext ctx) { if (ctx.Message is TransportData data && data.GetMetaDataValueByKey("DeviceName") == Device) { var zone1 = data.GetPayloadValueByName("Zone1Temp"); if (zone1 > Limit && DateTime.UtcNow - _lastWarning > Quiet) { _lastWarning = DateTime.UtcNow; LogWarning($"{Device} zone 1 is {zone1:0.0} degC, above {Limit} degC."); } } base.OnMessageReceive(ctx); } } } ``` Every function has this shape: one class that derives from `FunctionBase`, with the three-parameter constructor shown. `OnStarted` says what the function listens to; `OnMessageReceive` handles each message. The function's name is set from the code when you deploy: namespace and class name, here `Plant.OvenZoneWatch` (the screenshots show a copy in the namespace `DOCS`). Write the namespace as a block (`namespace Plant { ... }`) so it is picked up. Names must be unique. ## Step 3: Choose the gateways Open **Configuration** below the editor. **Gateways** lists where the function runs; a new function starts with **SYSTEM**. Add or remove gateways here. Once deployed, the list is locked until you undeploy. ## Step 4: Build Select **Build** (1). *Screenshot: A deployed function with the Build and Deploy buttons and the code in the editor* 1. **Build** compiles the code in the hub. "Compilation successful!" means it is ready; otherwise the message lists the errors with their lines. 2. **Deploy** sends it to the gateways. 3. The editor marks errors and warnings while you type. Press Ctrl+Shift+F (Cmd+Shift+F on a Mac) to format the code. The two buttons at its top right copy the code and switch to full screen. ## Step 5: Deploy Select **Deploy** and confirm. The hub saves the function, checks that it builds and starts, and sends it to each gateway in **Gateways**. Each gateway builds it again and starts it. The message names the gateways that confirmed, or the ones that did not answer. In the list, the function now shows **Deployed** and where it **Runs On**. *Screenshot: The function list with OvenZoneWatch deployed on the SYSTEM gateway* A gateway that restarts gets its deployed functions back from the hub. ## Step 6: Read its log entries Open the function, open **More items** (**...**) and select **Logs**. The list shows the log entries of this function only. Choose **Problems**, **Errors** or **All logs**, and select **Refresh** to load new ones. *Screenshot: The Logs window of the function with two warnings about oven zone 1 above 180 degC* Write to the log from your code with `LogInformation`, `LogWarning`, `LogError` and the other `Log...` methods. ## Change or stop a function - **Change it**: edit the code, **Build**, then **Deploy** again. Saving alone does not change what the gateways run. - **Stop it**: **Undeploy** stops it and removes it from its gateways. A deployed function cannot be deleted; undeploy it first. ## Limits - Some namespaces cannot be used, among them `System.IO`, `System.Diagnostics`, `System.Reflection`, `System.Data`, `System.Text.RegularExpressions` and `Microsoft.Win32`. The build names the one you used. Read and write databases through the helper methods of `FunctionBase` instead. - A function that throws too many unhandled errors is undeployed by the gateway; the limit is `ExceptionThresholdPerFunction` in the `[UserFunctions]` section of the configuration file (10 by default). - To protect the log, each function may write only a few error and critical entries per minute; `LogLevelPolicy` in `[UserFunctions]` sets how many (two of each per minute by default). ```toml [UserFunctions] ExceptionThresholdPerFunction = 10 LogLevelPolicy = ["Error:2 1m", "Critical:2 1m"] ``` ## What's next - [Functions SDK](https://proxus.io/docs/develop/functions-sdk): the base class, helpers and more examples. - [Configuration keys](https://proxus.io/docs/reference/configuration) - [Automation troubleshooting](https://proxus.io/docs/troubleshoot/automation) --- # Analyze > Look back at what your machines did. Dashboards, printable reports, reports sent on a schedule, and the data they can draw on. Source: https://proxus.io/docs/analyze **Analyze** turns stored data into dashboards and reports: production and energy over a shift, data quality per device, which rules fired most, how long devices were connected. In the hub, these screens are in the **Analyze** menu. ## What you find here | Screen | What it is for | | --- | --- | | **Dashboards** | Interactive pages of charts, tables and figures that refresh by themselves. Proxus ships ready-made ones; you can change them or build your own. | | **Reports** | Documents laid out in pages, to read on screen, print or export (PDF, Excel and others). Some ask for a device, a tag and a number of days before they run. | | **Scheduled Deliveries** | Runs a report at set times and sends the file by email. | | **Reporting Federation** | Shows whether dashboards and reports can join telemetry with the device, gateway, rule and alert lists. | Items whose names start with **[Proxus Built-in]** come with the product. They are added when the reporting federation is ready, and are updated with the product. ## Start here For live values and alarms right now, use [Monitor](https://proxus.io/docs/monitor) instead. --- # Use and build dashboards > Open a dashboard, change its period, refresh it, export it, import one from a file, and the rules a dashboard's own SQL query must follow. Source: https://proxus.io/docs/analyze/dashboards This guide shows how to open a dashboard and read it, change the period it covers, keep it up to date, and bring in a dashboard someone else made. The last part is for people who build dashboards with their own SQL queries. ## Before you start - A user role that may view dashboards. To change or create one, the role must also allow editing them. - Data in the history: dashboards show what the gateways have stored. ## Open a dashboard Go to **Analyze > Dashboards** and select a dashboard in the list (2). *Screenshot: The dashboard list with the Import Dashboard button and the built-in Operations Overview dashboard marked* 1. **Import Dashboard** brings in a dashboard from a file. See [Import a dashboard](#import-a-dashboard). 2. Dashboards whose names start with **[Proxus Built-in]** come with the product: | Dashboard | What it shows | | --- | --- | | **Operations Overview** | Gateways, devices, reporting devices, stored values and errors; values stored over time; values per device. | | **Fleet Availability** | Gateways, devices, enabled devices and profiles; devices per gateway; the device list. | | **Telemetry Freshness** | Devices that report, configured tags and value streams; the devices seen least recently. | | **Alert Operations** | Alerts, occurrences and rules firing; alerts by state and by rule. | | **Data Quality** | Data quality scores, their spread, and the devices with the lowest scores. | ## Read and filter it *Screenshot: The toolbar of an open dashboard with Switch to Design Mode, Auto Refresh and Refresh, and the export and parameter buttons in the dashboard title bar* 1. **Switch to Design Mode** opens the dashboard designer, if your role allows it. 2. **Auto Refresh** reloads the data by itself: **Off**, every **1s**, **5s**, **10s**, **30s** or **1 min**. 3. **Refresh** reloads the data now. 4. **Export To** (in the dashboard's title bar) saves the dashboard or one item as a file. 5. **Dashboard Parameters** sets the values the dashboard asks for, such as the number of **Days** it covers. *Screenshot: The Dashboard Parameters window with the Days parameter set to 7* Change **Days** and select **Submit**. **Reset** goes back to the dashboard's own value. Operations Overview and Telemetry Freshness have this parameter; it starts at 7. Inside the dashboard, select a bar, a row or a slice to filter the other items by it, where the dashboard was built that way. Hover over a chart to see the exact values. The full-screen button in an item's title shows that item alone. ## Make your own Do not change a built-in dashboard: it is replaced when the product updates it. Make a copy instead. 1. Open the dashboard and select **Clone...**. Give the copy a name. 2. Open the copy and select **Switch to Design Mode**. 3. Add items, change their data, and save. **Switch to View Mode** goes back. To start from an empty page, select **New** in the dashboard list. ### Data a dashboard can use The designer offers the hub's telemetry database. With the default ClickHouse telemetry database you can use: - `DeviceRawData`: every stored tag value, with its time, device, tag name (`Key`) and value (`NumericValue`, `StringValue`). - `DeviceMetrics` and `Logs`: device read statistics and log entries. - When the [reporting federation](https://proxus.io/docs/analyze/reporting-federation) is **Ready**: the lists from the hub, such as `proxus_reporting.Device`, `proxus_reporting.Gateway`, `proxus_reporting.Rule` and `proxus_reporting.Alert`, so that a query can show device names next to their values. If the telemetry database is PostgreSQL, only tables and views whose name contains `Device` are offered. ### Rules for your own SQL A dashboard may use a query you write. Before it runs, Proxus checks it, and refuses it with a message when it breaks one of these rules: | Rule | Message when broken | | --- | --- | | The query is not empty. | "Empty SQL." | | It starts with `SELECT`, `WITH`, a comment or `SET TIMEZONE`. | "Only SELECT/CTE (WITH), comments, or 'SET TIMEZONE' are allowed at the beginning." | | It is one statement. A second statement after a `;` is refused. | "Multiple statements are not allowed." | | After `WITH` parts, the query itself is a `SELECT`. | "After CTEs, only a SELECT statement is allowed." | | It contains none of these words: `UPDATE`, `DELETE`, `INSERT`, `MERGE`, `UPSERT`, `DROP`, `CREATE`, `ALTER`, `TRUNCATE`, `RENAME`, `ATTACH`, `DETACH`, `OPTIMIZE`, `SYSTEM`, `KILL`, `GRANT`, `REVOKE`, `COPY`, `CALL`, `EXEC`, `EXECUTE`. | "Security violation: The SQL keyword '...' is not permitted." | The words are checked as whole words, outside quotes and comments, in any case. A column named `Created` is fine; a column named `System` is not, unless it is quoted. The check adds no time limit and no row limit. Filter by time and add a `LIMIT` yourself, so a dashboard does not read the whole history: ```sql SELECT Time, NumericValue FROM DeviceRawData WHERE Key = 'Zone1Temp' AND Time > now() - INTERVAL 24 HOUR ORDER BY Time LIMIT 10000 ``` ## Import a dashboard 1. In the dashboard list, select **Import Dashboard**. 2. Choose the file. It must be a dashboard saved as XML, for example with **Export to XML** on another hub. The dashboard is added under the title stored in the file. If the file is not a dashboard, the message says so ("XML root is not a valid Dashboard definition."). To move a dashboard to another hub, open it, select **Export to XML**, and import that file on the other hub. ## What's next - [Reports](https://proxus.io/docs/analyze/reports): page-based documents to print, export or send. - [Reporting federation](https://proxus.io/docs/analyze/reporting-federation) - [Trend workspace](https://proxus.io/docs/monitor/trend-workspace): look at a few tags over time without building anything. --- # Run and export reports > Run a built-in or your own report, fill in its parameters, export it, and the list of reports that come with Proxus. Source: https://proxus.io/docs/analyze/reports This guide runs the built-in **Shift and Daily Summary** report for one tag of one machine and exports the result. Every report works the same way. The list of built-in reports is at the end. ## Before you start - A user role that may view reports. To change or create one, the role must also allow the report designer. - Data in the history for the device and period you want. ## Step 1: Open the report Go to **Analyze > Reports** and select the report in the list (3). *Screenshot: The report list with New Telemetry SQL Report, Copy Predefined Report and the built-in Shift and Daily Summary report marked* 1. **New Telemetry SQL Report** starts a new report on the telemetry database. See [Make your own](#make-your-own). 2. **Copy Predefined Report** makes an editable copy of the selected report. 3. The report to run. Reports whose names start with **[Proxus Built-in]** come with the product. The report opens in a viewer. If it has parameters, the **Parameters** panel opens on the right and the page says "Waiting for parameter values...". ## Step 2: Fill in the parameters *Screenshot: The Parameters panel of the report with device MFB_LYS_TUNNEL_OVEN, tag Zone1Temp, 7 days and the Submit button* 1. **Device**: pick the device. 2. **Tag**: pick the tag. The list offers the tags this device sent in the last 30 days. 3. **Days**: how many days back the report covers. It starts at 7. 4. Select **Submit**. **Reset** clears your choices. Pick a device and a tag before you submit: the tag reports read the values of the one tag you choose. ## Step 3: Read, print or export *Screenshot: The Shift and Daily Summary report for oven zone 1 with sample count, average, a chart by shift and a table by day* The toolbar above the page moves between pages, zooms, prints, and exports. Select the export button and choose a format to save the report as a file. Shift and Daily Summary shows one tag across days and the three fixed shifts **Shift 1 (00-08)**, **Shift 2 (08-16)** and **Shift 3 (16-24)**, with the average and the number of values per shift. To get a report by email at set times, see [Scheduled delivery](https://proxus.io/docs/analyze/scheduled-delivery). ## Built-in reports | Report | What it shows | Asks for | | --- | --- | --- | | **Asset Inventory** | Every device with its ID, gateway, profile and whether it is enabled. | Nothing | | **Fleet Health Executive Summary** | Availability, data quality and activity of all devices over the last 30 days. | Nothing | | **Data Quality Scorecard** | Accuracy, completeness, integrity and consistency per device, worst first. | Nothing | | **Device Connectivity and Uptime** | Request success rate, response time and last contact per device. | Nothing | | **Telemetry Freshness and Gaps** | Configured tags against the values actually received in the last 24 hours. | Nothing | | **Alert Pareto and Summary** | Which rules cause most alerts, how alerts are progressing, and what repeats most. | Nothing | | **Rule Effectiveness** | How often each rule fired, its latest activity, and rules that never fired. | Nothing | | **Operational Log Summary** | Reason codes, severity mix and recurring log events over the last 7 days. | Nothing | | **Scheduled Delivery Operations** | Every scheduled delivery and its runs. | Nothing | | **Tag Trend and Statistics** | One tag over time, how its values are spread, and its statistics. | Device, Tag, Days | | **Shift and Daily Summary** | One tag across days and shifts, with averages and value counts per shift. | Device, Tag, Days | | **Consumption and Counter** | Daily consumption of a counter tag, as the difference between its last and first reading of each day. | Device, Tag, Days | The periods of the reports without parameters are fixed (24 hours, 7 days or 30 days, as stated above). Built-in reports are added when the [reporting federation](https://proxus.io/docs/analyze/reporting-federation) is ready, and are updated with the product. To change one, copy it first. ## Make your own - **Copy Predefined Report** or **Clone...** makes a copy you can change. Open it with **Edit** to change it in the report designer. - **New Telemetry SQL Report** creates a report named "Telemetry Report" with the date and time, with a starting query over the stored values of the last seven days, and opens the designer. It is offered when the telemetry database is ClickHouse and your role may use the report designer. - **New** starts a report from the report wizard. A query you write in a report follows the same rules as a dashboard query: one `SELECT` (or `WITH` ... `SELECT`) statement, no statements that change data. See [Rules for your own SQL](https://proxus.io/docs/analyze/dashboards#rules-for-your-own-sql). ## What's next - [Scheduled delivery](https://proxus.io/docs/analyze/scheduled-delivery): send a report by email every day. - [Dashboards](https://proxus.io/docs/analyze/dashboards) - [Reporting federation](https://proxus.io/docs/analyze/reporting-federation) --- # Send a report on a schedule > Run a report every day, weekday, week or month and send it by email as a PDF or Excel file. Pause, run now, and read what each run did. Source: https://proxus.io/docs/analyze/scheduled-delivery At the end of this guide, the **Fleet Health Executive Summary** report is produced every weekday at 06:30 and sent by email as a PDF. ## Before you start You need: - A report that runs without asking anything. A scheduled run cannot fill in parameters, so choose a report without them (the built-in reports marked "Nothing" under **Asks for** in [Reports](https://proxus.io/docs/analyze/reports)), or a copy whose parameters have the defaults you want. - For email: an **Email Notification** channel with the SMTP server, user name, password, sender (`From`) and the recipients (`To`, and optionally `Cc` and `Bcc`, separated by `,` or `;`). See [Notification channels](https://proxus.io/docs/connect/notification-channels). The recipients come from the channel, not from the schedule; at most 25 in all. - A user role that may create scheduled deliveries. ## Step 1: Create the schedule Go to **Analyze > Scheduled Deliveries** and select **New**. *Screenshot: The scheduled delivery form with the Fleet Health Executive Summary report, the Weekdays preset at 6:30 AM, the email delivery box and the preview of the next run* Fill in: - **Name**: for example `Weekday fleet health summary`. **Owner** is you; only the owner or an administrator can run, pause or change the schedule's runs. 1. **Report**: the report to send. 2. **Schedule Preset**: **Daily**, **Weekdays** (Monday to Friday), **Weekly**, **Monthly** or **Custom**. **Weekly** asks for the **Weekly Day**, **Monthly** for the **Monthly Day** (1 to 28). 3. **Schedule Time**: the time of day. The preset and the time fill in **Schedule Expression** for you. 4. **Enable Email Delivery**: tick it, then choose the email **Delivery Channel** and, if you like, an **Email Subject**. Without a subject, the schedule's name is used. 5. **Next Run Preview** shows when it will run next, in the hub's time zone. Check it before you save. On the right: - **Artifact Format**: **Pdf** or **Xlsx**. - **Misfire Policy**: what to do when the hub was not running at the planned time. **Skip** leaves that run out; **Run once after recovery** runs it once when the hub is back. - **Overlap Policy**: what to do when the previous run is still busy. **Skip** or **Queue one**. - **Automatic Retry Limit**: how many times a failed run is tried again (0 to 3), and **Automatic Retry Delay Minutes** between tries. Retries also need `AutomaticRetryEnabled = true` in the configuration file. Select **Save**. The schedule is **Active** and runs at the next planned time. ### A custom schedule With **Custom**, write **Schedule Expression** yourself as a five-part cron expression: minute, hour, day of month, month, day of week. For example `0 8 * * 1-5` is 08:00 Monday to Friday, and `30 6 1 * *` is 06:30 on the first day of every month. The `H` form is not accepted. ## Step 2: Test it Select **Run Now** in the toolbar. One run is queued at once, using the saved settings. The **Executions** list below the form shows it: | Column | Meaning | | --- | --- | | **Occurrence** | The planned time of the run. | | **State** | **Planned**, **Claimed**, **Running**, **Succeeded**, **Failed**, **Blocked** or **Cancelled**. | | **Trigger** | **Scheduled**, **Manual** (Run Now), **Retry** or **Automatic retry**. | | **Started**, **Completed** | When it ran. | | **Failure Reason** | Why it failed, as a code (see below). | Select a failed or blocked run and use **Retry** to try it again, or **Cancel** to drop a run that has not started. | Failure Reason | Meaning and what to do | | --- | --- | | `delivery_not_enabled` | Email delivery is off, for this schedule (**Enable Email Delivery**) or for the whole hub (`ExternalDeliveryEnabled`). | | `delivery_failed` | The email could not be sent. Check the channel's SMTP settings and recipients. | | `delivery_ambiguous`, `provider_outcome_unknown` | The mail server did not confirm. The email may or may not have arrived. | | `artifact_failed` | The report could not be produced, for example because of its query or because the file exceeded 20 MB. | | `authorization_blocked` | The schedule is paused, its owner is no longer active, or it has no report. | | `worker_interrupted` | The hub stopped during the run. | > **Warning:** A schedule without **Enable Email Delivery** produces the file but sends nothing, and its runs end as **Failed** with `delivery_not_enabled`. There is no place in the hub to download that file, so always turn on email delivery for a schedule you want to use. ## Pause, restart, change - **Disable** in the toolbar pauses the schedule; **Enable** starts it again. The list shows **Active** or **Paused** in **Status**. - Changes to the time or the report apply from the next run. The list of schedules shows each one's **Report**, its **Schedule** in words ("Weekdays at 6:30 AM"), **Status**, where it **Delivers To** ("Email · channel name" or "In app only"), its **Last Run** and **Next Occurrence**. ## Copilot summaries instead of a report **Content** chooses what a delivery sends: a **Report** (the default), a **Copilot Shift Summary** (the last 8 hours) or a **Copilot Weekly Health Report** (the last 7 days). A summary needs no report: **Report** and **Output format** are hidden. It arrives as the e-mail itself, not as an attachment. The summary covers what the delivery's owner sees, their site included: devices that are not communicating, disconnected edge gateways, alarms compared with the period before, the noisiest rules and devices, open critical alarms and, for owners who see the whole plant, configuration problems. The numbers are counted by Proxus; when the owner may use [Copilot](https://proxus.io/docs/monitor/copilot) and has tokens left for the day, Copilot writes them up in the hub's language (the tokens count as the owner's). Otherwise the same numbers are sent as a plain list. ## Settings for the whole hub ```toml [ScheduledDelivery] # Email delivery is enabled by default; each schedule still requires its own opt-in. ExternalDeliveryEnabled = true # Automatic retry also requires a per-schedule retry limit from 1 to 3. AutomaticRetryEnabled = false # Zero disables artifact deletion. ArtifactRetentionDays = 0 ArtifactCleanupIntervalHours = 24 ``` | Key | Default | Meaning | | --- | --- | --- | | `ExternalDeliveryEnabled` | `true` | Set `false` to stop all email delivery at once. | | `AutomaticRetryEnabled` | `false` | Allows schedules with an **Automatic Retry Limit** to retry. | | `ArtifactRetentionDays` | `0` | Days to keep produced files before they are deleted. `0` keeps them. Up to 3650. | | `ArtifactCleanupIntervalHours` | `24` | How often old files are deleted, 1 to 168 hours. | As environment variables they are written `ScheduledDelivery__ExternalDeliveryEnabled` and so on. See [Configuration keys](https://proxus.io/docs/reference/configuration). ## What's next - [Reports](https://proxus.io/docs/analyze/reports) - [Notification channels](https://proxus.io/docs/connect/notification-channels) --- # Reporting federation > How dashboards and reports join stored values with the device, gateway, rule and alert lists, what the federation status means, and how to switch it off. Source: https://proxus.io/docs/analyze/reporting-federation Proxus keeps two kinds of data in two databases. The stored tag values (telemetry) are in the telemetry database, ClickHouse by default. The lists you manage in the hub (gateways, devices, profiles, tags, rules, alerts, scheduled deliveries) are in the hub's PostgreSQL database. A dashboard or a report that shows "average temperature per device name" needs both. The **reporting federation** makes the hub's lists readable from the telemetry database, so that one query can join them. It is not a link between several hubs or sites: it works inside one hub. ## What the hub sets up When the telemetry database is ClickHouse and the federation is switched on, the hub, shortly after it starts: 1. Creates a read-only user in PostgreSQL, named `proxus_reporting`, that may only read a fixed list of tables. 2. Creates a database `proxus_reporting` in ClickHouse whose tables read those PostgreSQL tables directly. 3. When both work, marks the federation **Ready** and adds or updates the built-in reports and dashboards. The tables are `Gateway`, `Device`, `DeviceProfile`, `DeviceProfileRegister` (the tags), `DeviceStatistics`, `Alert`, `Rule`, `ScheduledDelivery`, `ScheduledExecution` and `DeliveryAttempt`. In a query, write them with the database name, for example: ```sql SELECT d.DeviceName, count() AS Samples FROM DeviceRawData AS v INNER JOIN proxus_reporting.Device AS d ON v.DeviceId = toUInt32(d.Oid) WHERE v.Time > now() - INTERVAL 24 HOUR GROUP BY d.DeviceName ORDER BY Samples DESC ``` The data is read at query time, so a query always sees the current lists. Nothing is copied. ## The status screen **Analyze > Reporting Federation** shows one row: the state of the federation on this hub. It is read-only. *Screenshot: The Reporting Federation screen showing the status Ready with catalog version 1* | Status | Meaning | | --- | --- | | **Ready** | Both sides work. Dashboards and reports can use the `proxus_reporting` tables, and the built-in content is installed. | | **Pending** | The hub is setting it up. | | **Degraded** | Setting it up failed. The hub tries again every two minutes; **Retry After Utc** says when. | | **Disabled** | The federation is switched off in the configuration file. | **Reason Code** says why, for example `ready`, `initializing`, `federation_disabled`, `postgres_provisioning_denied` (the hub's database user may not create the reporting user), `postgres_provisioning_failed`, `clickhouse_mapping_failed` (ClickHouse could not reach PostgreSQL) or `federation_initialization_failed`. **Validated At Utc** is the last successful check, and **Catalog Version** the version of the table list. While the federation is not **Ready**, the `proxus_reporting` tables are not offered in the dashboard and report designers, and the built-in reports and dashboards are not installed. ## Switch it on or off ```toml [Reports.ClickHouse] # Offers the ClickHouse telemetry connection in the report designer. Enabled = true [Reports.PostgreSqlFederation] # Creates the read-only reporting user and the ClickHouse tables that read the hub database. Enabled = true ``` | Key | Default | Meaning | | --- | --- | --- | | `[Reports.ClickHouse] Enabled` | `true` | Offers the telemetry database as a data source in the report designer, and **New Telemetry SQL Report**. | | `[Reports.PostgreSqlFederation] Enabled` | `true` | Sets up the federation. `false` stops it and hides the `proxus_reporting` tables from the designers. | As environment variables: `Reports__ClickHouse__Enabled` and `Reports__PostgreSqlFederation__Enabled`. Restart the hub after a change. See [Configuration keys](https://proxus.io/docs/reference/configuration). The federation needs the telemetry database to be ClickHouse. ClickHouse must be able to reach PostgreSQL on the network with the address in the hub's database connection string (a `localhost` address is reached as `host.docker.internal`), and the hub's PostgreSQL user must be allowed to create a user. ## What's next - [Dashboards](https://proxus.io/docs/analyze/dashboards) - [Reports](https://proxus.io/docs/analyze/reports) - [Architecture](https://proxus.io/docs/concepts/architecture): where Proxus keeps which data. --- # Administer > Manage who can sign in and what they can do, the hub's certificates, license and configuration, and the logs and records you need when something fails. Source: https://proxus.io/docs/administer This section is for the person who looks after a Proxus hub: who may sign in, what each person may see and change, which certificates and license the hub uses, how it is configured, and where to look when something goes wrong. In the hub, **Users**, **Roles** and the **Certificate Store** are in the **Security** menu. The other screens are in the **Platform** menu. UNS permissions you also give from **Organize > UNS Explorer**. ## What you manage here | Screen | What it is for | | --- | --- | | **Users** | One entry per person or system that signs in. A user gets what its roles allow. | | **Roles** | Sets of permissions: which screens, which kinds of records, which actions, which parts of the Unified Namespace. | | **My Profile** | Your own account: change your password, see your roles. | | **White Labeling** | Your own application title and logo, if your license includes it. | | **License Info** | What your license allows and how close each edge gateway is to its capacity. | | **Certificate Store** | The platform's certificate authority, and every certificate for HTTPS, the hub's NATS server, the gateways, OPC UA connections and outbound targets. | | **Copilot Settings** | The AI services Copilot answers with, and their API keys. See [Set up Copilot](https://proxus.io/docs/administer/copilot-settings). | | **Config Editor** | The hub's configuration file, edited in the browser. | | **System Logs** | Warnings and errors from the hub and every edge gateway, and the support bundle. | | **Database Health** | Size, disk use and retention of the telemetry database. See [Monitoring](https://proxus.io/docs/operate/monitoring). | Every saved record also has an **Audit Trail** button that shows who changed what, and when. ## Start here Every connection of the platform can be encrypted with TLS: the hub's HTTPS (port `8443`), the NATS links between the hub and the gateways, the gateways' MQTT brokers (port `8883`), outbound targets and OPC UA connections. HTTPS and the NATS links are encrypted by default. The plain ports `8080` (HTTP) and `1883` (MQTT) stay open for local access and devices without TLS until you close them: see [Security hardening](https://proxus.io/docs/operate/security#hardening-checklist). The certificates for all TLS connections come from the Certificate Store. See [Security](https://proxus.io/docs/operate/security#what-is-encrypted). To install, upgrade, back up or secure the installation itself, see [Install and operate](https://proxus.io/docs/operate). --- # Users and roles > Add users, give them roles, build a role from an existing one, and set the password, lockout and session rules of the hub. Source: https://proxus.io/docs/administer/users-and-roles At the end of this guide, a new person can sign in to the hub and sees only what their role allows. A **user** is one account. A **role** is a set of permissions. A user can have several roles, and gets everything those roles allow together. ## Before you start - Sign in with a user that has the **Administrators** role. - Decide what the new person must be able to do: which screens, which records (devices, rules, reports), and which parts of the plant. ## The roles Proxus starts with A new hub has ten roles: **Administrators**, **Default** and eight built-in roles for the usual jobs in a plant. Give people one of the built-in roles, combine several (a user gets everything their roles allow together), or copy one and change it. | Role | For | Typical person | | --- | --- | --- | | **Administrators** | Everything. **Is Administrative** is ticked, so no other permission is checked. The user **Admin** has this role. | Whoever installed the hub; an emergency account | | **Viewer** | Watches; changes nothing. | Control-room screen, plant manager, visitor | | **Operator** | Takes and resolves alarms, keeps trend views and notes. | Shift operator, maintenance technician | | **Analyst** | Designs dashboards and reports, sets up scheduled deliveries, runs read-only SQL. | Quality, efficiency or energy lead | | **Engineer** | Builds devices, profiles, rules, pipelines and functions and tries them; does not put them live. | Automation engineer, integrator | | **Commissioning Engineer** | Everything the engineer does, and puts it live: pipelines that write to devices, function deployment, switching collection on and off. | Senior automation engineer | | **IT Administrator** | Users, certificates, configuration, license, gateway installation and terminal; reads the process settings but does not change them. | IT / OT infrastructure team | | **Auditor** | Reads everything, the audit trail included; changes nothing. | Quality assurance, internal audit, cyber security | | **Integration** | No menu; reads through the REST API, OData and MCP. | MES or ERP link, BI tool, AI assistant | | **Default** | Almost nothing: the user's own **My Profile**, changing their own password, their own screen layout, their own entries in the audit trail and reading the license. No user has this role when the hub is new. | none | Two rules hold across the roles. **Who builds does not put it live**: an engineer publishes a pipeline in Shadow and sees what it would do; only a commissioning engineer publishes it Active (where it can write to devices) or deploys function code. **Who runs the infrastructure does not run the process**: the IT administrator installs gateways and opens their terminal but cannot change devices, rules or pipelines. Built-in roles stay current: when Proxus adds a screen, the update gives it to the built-in roles that should have it. A built-in role you change shows **customized** at the top of its page, and updates leave it as you made it. A role of your own with a built-in role's name is left alone, and that built-in role is not created. ### What each role sees and changes **read**: sees the records · **edit**: also changes them · **full**: also creates and deletes them · **own**: only the records the user made (their trend views, deliveries, profile and audit entries) · **none**: not in the menu. | Area | Viewer | Operator | Analyst | Engineer | Commissioning Engineer | IT Administrator | Auditor | Integration | | --- | --- | --- | --- | --- | --- | --- | --- | --- | | Operations Center, topology, Copilot | read | read | read | read | read | read | read | none | | Trend Workspace | read | own | own | own | own | read | read | read | | Alerts | read | edit | read | edit | edit | read | read | read | | Devices, device profiles, import | read | read | read | full | full | read | read | read | | Edge gateways | read | read | read | read | read | full | read | read | | UNS Explorer, health checks | read | read | read | read | read | read | read | read | | Outbound targets, notification channels | none | none | read | full | full | read | read | none | | Rules, rule actions | read | read | read | full | full | read | read | read | | Pipelines | none | read | read | full | full | read | read | none | | Functions | none | none | none | full | full | none | read | none | | App templates | none | none | none | read | full | read | read | none | | Dashboards, reports | read | read | full | read | read | read | read | read | | Scheduled deliveries | none | none | own | own | own | none | read | none | | Users, roles | own | own | own | own | own | full | read | none | | Certificate store | none | none | none | read | read | full | read | none | | System logs, database health | none | none | none | read | read | read | read | none | | Configuration, license, brand, demo data | none | none | none | none | none | full | read | none | | Copilot settings and usage | none | none | none | none | none | full | read | none | | Audit trail | own | own | own | read | read | read | read | none | UNS Topic Permissions decide which part of the plant a role sees: the UNS Explorer, and the devices, alarms and values everywhere else. Built-in roles start with none (every site, empty UNS Explorer), so add the plant paths each role should see. See [UNS permissions](https://proxus.io/docs/administer/uns-permissions). ### Capabilities Some buttons have an effect beyond the record: they write to devices, run code on gateways or change the platform. They need a **capability** as well as the record permission: an engineer may change a pipeline, but publishing it Active needs **Write to devices**. A button the role has no capability for is hidden, and refused if called through the API or Copilot. *Screenshot: The Capabilities tab of the built-in Engineer role: Try pipelines granted, Write to devices not* 1. **Write to devices** is not ticked for the Engineer: the Publish Active button is hidden for engineers. 2. **Try pipelines** is ticked: engineers validate and publish in Shadow. | Capability | Viewer | Operator | Analyst | Engineer | Commissioning Engineer | IT Administrator | Auditor | Integration | | --- | --- | --- | --- | --- | --- | --- | --- | --- | | **Write to devices** | | | | | ✓ | | | | | **Deploy code** | | | | | ✓ | | | | | **Start / stop data collection** | | | | | ✓ | | | | | **Try pipelines** | | | | ✓ | ✓ | | | | | **Build functions** | | | | ✓ | ✓ | | | | | **Handle alarms** | | ✓ | | ✓ | ✓ | | | | | **Send test messages** | | | | ✓ | ✓ | | | | | **Design dashboards and reports** | | | ✓ | | | | | | | **Run deliveries** | | | ✓ | ✓ | ✓ | | | | | **Export** | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | | **SQL queries** | | | ✓ | | | | | | | **Install app templates** | | | | | ✓ | | | | | **Install gateways** | | | | | | ✓ | | | | **Gateway terminal** | | | | | | ✓ | | | | **Manage certificates** | | | | | | ✓ | | | | **Configure the platform** | | | | | | ✓ | | | | **Manage the license** | | | | | | ✓ | | | | **Manage users and roles** | | | | | | ✓ | | | | **Support bundle** | | | | | | ✓ | | | The built-in roles' **Copilot Access**: **Ask questions** for Viewer, Operator, Analyst, IT Administrator and Auditor; **Ask and propose changes** for Engineer; **Ask, propose changes and run actions** for Commissioning Engineer; **No access** for Integration. Running an action through Copilot still needs the button's capability above. > **Warning:** A new hub ships with one user, **Admin**, with an empty password. Give it a password before anyone else can reach the hub. Hubs upgraded from an earlier version may also have a user **APIAdmin** with a password that was the same in every installation: give it a new password with **Reset Password**, or clear **Is Active**. See the [security checklist](https://proxus.io/docs/operate/security). ## Add a user Go to **Security > Users** and select **New** (1). *Screenshot: The user list with the New button, and the Status and Roles columns marked* 1. **New** opens an empty user. 2. **Status** shows **Active**, **Disabled** or **Locked** (too many wrong passwords). 3. **Roles** lists the roles of each user, or **No role**. On the new user: 1. Enter the **User Name**. This is the name the person types to sign in. 2. Leave **Is Active** ticked. Clear it later to stop the user from signing in without deleting the account. 3. Tick **Force Password Change**. At the first sign-in, Proxus asks the user to choose a password that follows the [password rules](#password-rules). 4. Under **Roles**, select **Link** and pick one or more roles. 5. Select **Save**. > **Note:** A new user has no password until they choose one. Until that first sign-in, anyone who knows the user name can sign in with an empty password. To avoid this, open the saved user, select **Reset Password**, give a temporary password and tell it to the person on another channel. ## Change a user Open the user from the list. *Screenshot: A user page with the Reset Password button, the Account group, the Roles list and the collapsed Session group marked* 1. **Reset Password** sets a new password for this user. Use it when someone forgot theirs. 2. **Account**: the user name, **Is Active** and **Force Password Change**. 3. **Roles**: **Link** adds a role, **Unlink** removes it. 4. **Session**: **Session Length** is how long the user stays signed in without any input. The browser then signs out. It is also shown at the top. The default is 30 minutes. `00:00:00` means no limit. Users change their own password on **Platform > My Profile** with **Change My Password**. ## Start from a built-in role The quickest role is a copy of a built-in one, changed where your plant differs: for example an operator role that sees only one site. 1. Go to **Security > Roles** and select **New from Built-in Role**. 2. Pick the **Built-in Role** and give the new role a **Name** (left empty: the built-in role's name with "(copy)"). 3. Select **Create**. The new role opens with the built-in role's permissions, capabilities and Copilot access. Change what differs and add its UNS Topic Permissions. A role made from a built-in role says so at the top of its page (**Based on built-in role**), and **customized** once it differs. Two more buttons work on such a role and on the built-in roles themselves: - **Compare with Built-in Role** lists what differs: what the role sees and changes per area, capabilities added or removed, menu items, Copilot access, and how many other rules (field, record and action rules) only one of them has. - **Revert to Built-in Role** undoes those differences after a confirmation. The role's users and UNS Topic Permissions stay. It is available when the role differs, or when its built-in role has a newer version (the top of the page then says so). A copy you have not changed (UNS rules and users do not count) is brought up to date with its built-in role like the built-in role itself. ## Build a role Go to **Security > Roles**, select **New**, give the role a **Name** and save it. Then add permissions. *Screenshot: A role page with Import Permissions, the Permission Policy field and the permission tabs marked* 1. **Import Permissions...** copies permissions from another role into this one. See the next section. 2. **Permission Policy** is what the role may do with anything you have not listed: **Deny all by default**, **Read only all by default** or **Allow all by default**. Start from **Deny all by default** and add what is needed. 3. The permission tabs: - **Users**: who has this role. - **Type Permissions**: one row per kind of record (**Target Type**), for example devices or rules, with **Read**, **Write**, **Create**, **Delete** and **Navigate**. - **Navigation Permissions**: which menu items the role sees. - **Denied Actions**: buttons the role may not use, even where it may change the record. - **Capabilities** (the first tab): the buttons with an effect on the plant, the gateways or the platform, in three groups (Process, Operations, Platform), each with what it opens. A new role has none. Roles made before 2.0.0 kept what they could do: every capability their Denied Actions left open, except **SQL queries**. Below the tabs, **UNS Topic Permissions** limits which parts of the plant the role sees. See [UNS permissions](https://proxus.io/docs/administer/uns-permissions). The summary at the top of the page counts what the role has: users, object types, menu items, capabilities and its **Site scope** (the paths its UNS rules open and close, or **All sites**). A built-in role also shows which one it is, and **customized** once you changed it. A user who manages users and roles without being an administrator (the **IT Administrator** role) cannot change the **Administrators** role or an administrator, cannot change a role they hold, and cannot change their own roles. Leave **Is Administrative** cleared for every role except one for administrators, and leave **Can Edit Model** cleared. ## Copy permissions from another role To make a role that is like an existing one, start from that role's permissions instead of adding them one by one. 1. Create and save the new role (for example `Shift supervisor`). 2. Select **Import Permissions...**. 3. Fill in the dialog and select **Import Permissions**. *Screenshot: The Import Permissions dialog with the Source Role field, the Overwrite existing option and the Import Permissions button marked* 1. **Source Role**: the role to copy from. The permissions are copied into the role you have open. 2. The four **Copy ...** boxes choose what is copied: navigation, type, action and UNS topic permissions. All are ticked by default. **Overwrite existing (instead of merge)** first removes the chosen kinds of permission from this role. Without it, the copied permissions are added and exact duplicates are skipped. 3. **Import Permissions** copies and saves. The message "Permissions imported into" and the role name confirm it. After the import, adjust the role. The source role does not change, and later changes to it are not copied again. ## Password rules The password policy is in the `[Security.Password]` section of the [configuration file](https://proxus.io/docs/administer/configuration). Proxus applies it in three places: when a user must choose a new password at sign-in, when a user changes their own password with **Change My Password**, and when an administrator sets one with **Reset Password**. A password that breaks a rule is refused with a message that says which rule. Restart the hub after you change the section. ```toml [Security.Password] MinLength = 6 MaxLength = 128 RequireUppercase = 0 # at least this many capital letters RequireLowercase = 0 RequireDigits = 0 RequireSpecialCharacters = 0 AllowedSpecialCharacters = "!@#$%^&*()_+-=[]{}|;:,.<>?" PasswordHistory = 5 # the last 5 passwords cannot be chosen again PasswordExpirationDays = 90 # a new password is required after 90 days PasswordExpirationWarningDays = 14 # warning at sign-in 14 days before PreventCommonPasswords = true # refuse common passwords and the user name PreventKeyboardPatterns = false # refuse qwerty, asdfgh, 123456 and similar PreventRepeatedCharacters = false MaxRepeatedCharacters = 3 RequireChangeOnFirstLogin = true # new users start with Force Password Change ticked TempPasswordExpirationHours = 24 # a reset password stops working after 24 hours unused ``` For a stricter policy, set for example `MinLength = 12`, `RequireUppercase = 1`, `RequireDigits = 1` and `RequireSpecialCharacters = 1`. What the time-based rules do: - **Expiry**: once a password is older than `PasswordExpirationDays`, the user must choose a new one at the next sign-in. The check runs every hour. When a hub is upgraded to 2.0.0, the age of every existing password starts at that first start, so nobody is locked out by the upgrade. - **Temporary passwords**: a password set with **Reset Password** must be replaced at the next sign-in. If the user does not sign in within `TempPasswordExpirationHours`, the password stops working and an administrator resets it again. - **History**: the user cannot choose any of their last `PasswordHistory` passwords again. Proxus keeps only their hashes, never the passwords themselves. A password set with **Reset Password** does not have to be new. ## Lockout after wrong passwords After a number of wrong passwords in a row, the account is locked for a short time and shows **Locked** in the user list. The `[Security]` section sets this: ```toml [Security] Lockout.Enabled = true Lockout.MaxFailedAccessAttempts = 3 Lockout.DefaultLockoutTimeSpan = 30 # seconds ``` ## Sign-in time and automatic sign-out When a user does nothing in the browser for their **Session Length** (see above), Proxus signs them out and shows the sign-in page. Input in any tab of the hub counts for all of them. For screens in a control room that must stay signed in, give that user `00:00:00` (no limit) and a role that can only read. ## What's next - [Limit a role to parts of the plant](https://proxus.io/docs/administer/uns-permissions) - [See who changed what](https://proxus.io/docs/administer/audit-trail) - [Secure the installation](https://proxus.io/docs/operate/security) --- # UNS permissions > Limit a role to parts of the plant. Allow or deny a branch of the Unified Namespace, such as one site or one line, for everyone with that role. Source: https://proxus.io/docs/administer/uns-permissions At the end of this guide, users of a role see only the sites, areas and devices of the Unified Namespace (UNS) you allowed, and across the platform only those devices, their alarms and their values. For example, the team in Lyon sees `Meridian/Lyon_Foods_Plant` and everything under it, and nothing of Rotterdam. ## Before you start - Sign in with a user that has the **Administrators** role. - The role exists and is not administrative. See [Users and roles](https://proxus.io/docs/administer/users-and-roles). - The devices have a place (enterprise, site, area...) so that they appear in the UNS. See [Unified Namespace](https://proxus.io/docs/concepts/unified-namespace). ## How the rules work A UNS permission is a rule on a role: a **path** in the UNS and an **Access** of **Allow** or **Deny**. - A path covers itself and everything under it. `Meridian/Lyon_Foods_Plant` covers every area, line and device of that site. There are no wildcards: MQTT signs such as `+` and `#` are removed when the rule is saved. - Paths are compared segment by segment and are case-sensitive. `Meridian/Lyon` does not cover `Meridian/Lyon_Foods_Plant`. - **Deny** wins over **Allow**. Allow a site and deny one line in it to hide only that line. - A user with several roles gets what any of them allows: two site roles open both sites, and one role without UNS rules that reads devices opens every device. - A role with no rule is not limited to a site: it sees every device it may read, but nothing in the UNS Explorer. A role with only **Deny** rules sees every device except the denied branches, and nothing in the UNS Explorer. - Administrative roles always see everything; their rules are not used. The rules decide which part of the plant a role works in; what it may do there (read, change) comes from its other permissions. A device cannot be saved outside the role's paths, for example moved to another site. ## Allow a branch from the UNS Explorer 1. Go to **Organize > UNS Explorer**. 2. Right-click the node you want to give access to, for example the site `Lyon_Foods_Plant`. 3. Select **Allow Access to Role...**, or **Deny Access for Role...** to hide it. 4. In the dialog, select the role and then **Apply**. *Screenshot: The UNS Explorer right-click menu on a site, with Allow Access to Role and Deny Access for Role marked* 1. **Allow Access to Role...** adds an allow rule for this node and everything under it. 2. **Deny Access for Role...** adds a deny rule. These menu items are only shown to administrators. *Screenshot: The Allow Access to Role dialog with the path Meridian/Lyon_Foods_Plant, the role list and the Apply button marked* 1. **Path** is the UNS path of the node you clicked. 2. The list shows every role that is not administrative. 3. **Apply** saves the rule. If the role already has a rule for this path, it is updated and turned on again. ## Add or change rules on the role Go to **Security > Roles**, open the role and look at **UNS Topic Permissions** below the permission tabs. - **New** adds a rule by hand: type the **ISA-95 Topic Prefix** (the path, such as `Meridian/Lyon_Foods_Plant/Packaging`) and choose the **Access**. - **Paste UNS Path** adds an allow rule for a path you copied with **Copy Path** in the UNS Explorer right-click menu. - Clear **Is Enabled** to switch a rule off without deleting it. *Screenshot: A role limited to the Lyon site: the Site scope cell of the summary and the UNS rule Meridian/Lyon_Foods_Plant marked* 1. **Site scope** in the summary at the top of the role page: how many rules the role has and which paths they open and close, or **All sites** when it has none. 2. Each rule shows its path (**ISA-95 Topic Prefix**), its **Access** and whether it is enabled. ## Where the rules apply | Place | Effect | | --- | --- | | **UNS Explorer** | Nodes outside the allowed paths are hidden. The parents of an allowed node stay visible so the user can open it. Device and data point counts count only what the user sees. | | Devices: device list and page, Operations Center, plant map, Trend Workspace, Copilot | Only devices in the allowed paths are listed. A device page opened by its link is refused. | | **Alerts** | Only the alarms of those devices. An alarm without a device belongs to no site and is hidden. | | Device telemetry and trend notes | Only the rows of those devices. | | AI agents through the [MCP server](https://proxus.io/docs/develop/mcp) | Devices and values outside the allowed paths are not returned. | | **Dashboards** and **Reports** | Every query reads only the rows of those devices: telemetry, device metrics, devices, alarms and device statistics. Pipeline signal tables return no rows. A SQL query with its own `SETTINGS`, a table function (such as `remote` or `url`) or system tables is refused, and a query built by picking tables instead of SQL returns no rows (a report with one is refused). | | **Scheduled deliveries** | A delivery runs with the site scope of the user who set it up (its owner): its recipients get what that user sees. | | Free SQL: the MCP `telemetry_query` tool and the telemetry query of the REST API | Closed to a user whose roles are limited to a site, even with the **SQL queries** capability: a query cannot be limited to a site. | Gateways, outbound targets, notification channels, rules, pipelines and functions do not carry a site; the role's record permissions decide them. > **Warning:** UNS permissions do not limit the built-in MQTT broker. A client that connects to the broker with a valid token reads topics regardless of these rules. Protect the broker with its own tokens. See [MQTT](https://proxus.io/docs/develop/mqtt). ## What's next - [Users and roles](https://proxus.io/docs/administer/users-and-roles) - [The UNS Explorer](https://proxus.io/docs/organize/uns-explorer) --- # Certificates > The Certificate Store is the platform's certificate authority. Renew and trust certificates, use your corporate CA, and choose the hub's HTTPS certificate. Source: https://proxus.io/docs/administer/certificates At the end of this guide, you know where every certificate of your Proxus installation comes from, how to make browsers and devices trust it, and how to renew or replace it. The **Certificate Store** keeps all certificates in the hub's database and acts as the platform's own certificate authority (CA), so the hub, every edge gateway, your OPC UA connections and your outbound targets use the same certificates. ## Before you start - Sign in with a user that has the **Administrators** role. - To use your organization's CA: the CA certificate with its private key as a `.pfx` or `.p12` file (a password is allowed). - For a single certificate from your own certificate authority: the certificate and its private key, as a `.pfx` or `.p12` file without a password, or as a `.pem`, `.crt` or `.cer` file with a `.key` file. ## The platform CA On its first start, the hub creates the **Proxus Platform CA**, valid for 20 years. Every certificate the platform needs for itself is issued by it: - the hub's HTTPS certificate (on new installations); - the certificate of the hub's NATS server, which carries all traffic between the hub and the edge gateways; - each edge gateway's certificate, for its HTTPS port and its MQTT broker. Because all of them chain to one CA, a browser, SCADA system or MQTT device needs to trust only that CA. Select **Download CA** to get it (see [Make browsers and devices trust the platform](#make-browsers-and-devices-trust-the-platform)). ## What the certificates are used for | Use | Where it comes from | | --- | --- | | HTTPS for the hub's web interface (port `8443`) | The certificate marked **Default**. On new installations it is issued by the platform CA. | | The hub's NATS server (ports `4222`, `7422` and, on Kubernetes HA, `6222`) | **Proxus Hub NATS**, issued and renewed automatically. | | Each edge gateway's HTTPS port and MQTT broker (port `8883`) | "*gateway name* (gateway *N*)", issued by the hub when the gateway asks for it. | | Proxus's own certificate when it connects to an OPC UA server, and the OPC UA servers it trusts | The OPC UA connection settings of a device profile, and the store's trust list. See [OPC UA](https://proxus.io/docs/connect/devices/opc-ua). | | Client certificates and trusted server certificates of outbound targets | **Client Certificate** and **Trusted Server Certificate** on the target. See [Outbound targets](https://proxus.io/docs/connect/outbound-targets). | ## The Certificate Store Go to **Security > Certificate Store**. *Screenshot: The Certificate Store list with the Upload, Self-Signed, Set as Default, Trust and Reject buttons marked* 1. **Upload** imports a certificate file. 2. **Self-Signed** creates a new self-signed certificate. 3. **Set as Default** makes the selected certificate the hub's HTTPS certificate. Only a server certificate with its private key can be the default; the button is unavailable on the others. 4. **Trust** marks the selected certificate as trusted for OPC UA. 5. **Reject** marks it as rejected, so it is no longer used. **Trust** and **Reject** work only on certificates of OPC UA servers: certificates whose private key is not in the store and that the platform does not use itself. On the Platform CA, the hub's HTTPS and NATS certificates, the gateways' certificates and the sign-in key certificate the buttons are unavailable, and a gateway's report of an OPC UA server cannot change them either. The store also has these actions: | Action | What it does | | --- | --- | | **Use Corporate CA** | Makes your organization's CA sign the platform's certificates from now on. See [Use your corporate CA](#use-your-corporate-ca). | | **Download CA** | Downloads the CA certificates (public certificates only, PEM format, no private key) to install as trusted elsewhere. | | **Renew** | Replaces one selected certificate with a new one from the platform CA. See [Renew a certificate](#renew-a-certificate). | | **Refresh** | Checks the expiry dates now. | | **Delete** | Deletes the selected certificate after you confirm. See [Certificates that cannot be deleted](#certificates-that-cannot-be-deleted). | **Trust View** shows **All**, only **Trusted** or only **Rejected** certificates. The **Status** column shows **Active**, **Expiring soon** (less than 30 days left), **Expired** or **Disabled** (rejected). Proxus checks the dates once a day and writes a warning to the [system logs](https://proxus.io/docs/administer/system-logs) for every certificate that expires within 30 days. The **Usage** column names everything the certificate is for, for example **MQTT Broker, Gateway HTTPS**. ### Certificates on a new installation A new hub creates these on its first start. You do not need to add any of them: | Certificate | What it is for | | --- | --- | | **Proxus Platform CA** | Signs the platform's certificates. | | **Proxus Data Protection** | Protects the hub's sign-in keys. | | **Proxus Hub HTTPS** | The hub's web interface on port `8443`. | | **Proxus Hub NATS** | The hub's message server. | | **SYSTEM (gateway 1)** | The built-in gateway's HTTPS and MQTT broker. Every gateway you install gets one like it. | ### Previous versions of renewed certificates The list shows the certificates in use. When a certificate is renewed, its previous version is kept for 30 days and then deleted automatically, unless an outbound target or a device profile still uses it. Deleting a gateway also deletes its certificates. ### What a certificate is used by Open a certificate to see its details. These fields tell you what depends on it: | Field | What it shows | | --- | --- | | **Used By** | Everything that uses this certificate, for example "Signs the platform's certificates", "Trusted by every platform service", "Hub HTTPS", "Protects the hub's sign-in keys", "Hub NATS server", "Gateway 2: connection to the hub, HTTPS, MQTT broker", "OPC UA client identity", "Trusted OPC UA server", "Rejected OPC UA server", or the names of the outbound targets that use it as client certificate or trusted server certificate. | | **Signs Platform Certificates** | Ticked on the CA that issues the platform's certificates. | | **Renewed Automatically** | Ticked on certificates the platform issued and renews by itself. | | **Usage** | What the certificate is for, for example **Platform**, **NATS Server**, **NATS Client**, **MQTT Broker**, **Gateway HTTPS**, **Certificate Authority** or **Sign-in Key Protection**. | Check **Used By** before you reject or replace a certificate. ### Certificates that cannot be deleted The store refuses to delete: - the CA that signs the platform's certificates; - the certificate that protects the hub's sign-in keys; - a CA whose certificates are still in use; - any certificate an outbound target or a device profile uses. The default HTTPS certificate cannot be deleted either. Make another one the default first. ## Make browsers and devices trust the platform 1. In **Security > Certificate Store**, select **Download CA**. You get a PEM file with the CA certificates. It has no private key, so you can hand it out freely. 2. Install it as a trusted root certificate where it is needed: on users' computers (or through your company's device management), in SCADA systems and other tools that call the hub, and on MQTT devices that connect to a gateway's broker on port `8883`. Browsers then open the hub over HTTPS without a warning, as long as the address they use is one of the names in the hub's certificate (see [The hub's HTTPS certificate](#the-hubs-https-certificate)). ## Use your corporate CA If your organization runs its own certificate authority, let it sign the platform's certificates. Clients that already trust your corporate CA then trust Proxus without any extra step. 1. Select **Use Corporate CA**. 2. Choose the CA file: a `.pfx` or `.p12` file with the CA certificate and its private key. Enter its password if it has one. 3. Confirm. From then on, your CA signs every certificate the platform issues. The Proxus Platform CA stays trusted until the certificates it issued are renewed, so nothing stops working in between. To move everything to your CA at once, renew the existing certificates. The store refuses a file that is not a CA, that has no private key, or that expires within 30 days. ## Renew a certificate 1. Select one certificate. 2. Select **Renew** and confirm. The new certificate comes from the platform CA. It has the same names and usage as the old one, a new key, and a validity of two years. Everything that used the old certificate moves to the new one: the hub's HTTPS, outbound targets and OPC UA connections. - A self-signed certificate is renewed into one issued by the platform CA. - A certificate issued outside Proxus cannot be renewed here. Renew it where it was issued and upload it again. - A CA is not renewed here. ### Automatic renewal Certificates the platform issued itself (the hub's NATS certificate, the gateways' certificates, and the others marked **Renewed Automatically**) are renewed 30 days before they expire. The hub checks once a day. Nothing has to be restarted: the hub's NATS server loads its new certificate while gateways stay connected, and each gateway gets its new certificate the next time it asks. ## The hub's HTTPS certificate The hub serves HTTPS on port `8443` by default, with the certificate marked **Default**. On a new installation, the hub's certificate is issued by the platform CA and covers: - the machine's name and its IP addresses; - `localhost`; - the names you list in `[Service]` `PublicHostNames` in `Proxus-config.toml` (separated by commas), for example the DNS name users type or the address of a NAT. ```toml [Service] PublicHostNames = "proxus.lyonfoods.local, 203.0.113.10" ``` An installation upgraded from an earlier version keeps its self-signed **Proxus (Self-Signed)** certificate. To get one that browsers trust once they trust the platform CA, select it and select **Renew**. The renewed certificate covers the hub's names. ### Change the hub's HTTPS certificate 1. Generate, upload or renew the new certificate. It must be a server certificate with its private key. A CA, a client certificate and the platform's own NATS, gateway and sign-in certificates cannot be the default. 2. Select it and select **Set as Default**, then confirm with **Set as default**. The hub uses the new certificate within a minute. You do not restart anything, and nobody is signed out: the keys that protect sign-ins are protected by a separate certificate (usage **Sign-in Key Protection**), not by the HTTPS certificate. An upgraded installation keeps its current default certificate for that purpose. How to turn HTTPS off, send all HTTP traffic to HTTPS, or publish HTTPS on another port is in [Security](https://proxus.io/docs/operate/security#https). ## Protect the store's private keys The private keys in the store are kept encrypted. The key that decrypts them is not in the database: | Installation | Where the store key is | | --- | --- | | Docker | `keys/STORE/certificate-store.key` in the config folder (the `config` volume). | | Kubernetes HA | `keys/STORE/certificate-store.key` on the hub's shared config disk. | | Any | Or the environment variable `PROXUS_CERTIFICATE_STORE_KEY` (a base64 value of 32 bytes), which you manage yourself. | > **Danger:** Back up the store key together with the config folder and the database. Without it, the certificates in a restored database cannot be read, and every certificate has to be created or uploaded again. See [Backup and restore](https://proxus.io/docs/operate/backup-and-restore). Certificates stored by an earlier version are encrypted automatically a few minutes after the first start of 2.0.0. ## Generate a self-signed certificate Use a self-signed certificate for tests, or where every client is told to trust it. Browsers show a warning for a self-signed certificate. In most cases, a certificate from the platform CA is the better choice. 1. Select **Self-Signed**. 2. Fill in the dialog and select **Generate**. *Screenshot: The Generate Self-Signed Certificate dialog with Subject, Subject Alternative Names, Validity and Usage marked* 1. **Subject (CN)**: the certificate's name, for example `proxus.lyonfoods.local`. 2. **Subject Alternative Names**: every name and IP address clients use to reach the hub, separated by commas, for example `proxus.lyonfoods.local, 10.20.0.15`. The subject and `localhost` are always added. 3. **Validity (Years)**: from 1 to 10. The default is 2. 4. **Usage**: what the certificate is for. **Platform** is the hub's own use. The certificate gets a 2048-bit RSA key and is listed as "*subject* (Self-Signed)". To turn it into one issued by the platform CA later, select it and select **Renew**. ## Upload a certificate from your certificate authority To use one certificate from your company's certificate authority, for example for the hub's HTTPS, upload it. Make sure the hub's DNS name is in its subject alternative names. 1. Select **Upload**. 2. Choose the files: one `.pfx` or `.p12` file, or a `.pem`, `.crt` or `.cer` certificate together with its `.key` file. A file whose name contains `ca` is read as the certificate authority's chain. 3. The certificate appears in the list. A certificate that is already in the store is refused with "Certificate already exists". A `.pem`, `.crt` or `.cer` file without a key is imported as a public certificate only. You can trust it, or choose it as an outbound target's **Trusted Server Certificate**, but you cannot make it the default. > **Note:** A `.pfx` or `.p12` file that is protected with a password cannot be uploaded with **Upload**. Export it again without a password, or upload the certificate and key as `.pem` and `.key` files. (**Use Corporate CA** accepts a password.) ## Trust or reject an OPC UA server certificate Proxus connects only to OPC UA servers whose certificate is trusted. The trust list lives in the Certificate Store and applies to every gateway: each gateway copies it every minute, so a **Trust** or **Reject** here takes effect on all gateways within a minute. ### Trust a server that was refused When a gateway meets an OPC UA server certificate it does not trust, it refuses the connection and reports the certificate to the hub. 1. In **Security > Certificate Store**, set **Trust View** to **Rejected**. 2. Find the certificate. It is named "OPC UA server *name* (*address*)". 3. Check that you recognise the server, then select the certificate and select **Trust**. The refused devices connect on their next retry. Other ways a server certificate becomes trusted: - The **Trust** step of the device connect wizard records the server's certificate as trusted in the store, for every gateway. - **Trust Server Certificate** on a device accepts the server's certificate at the first connection and records it in the store as trusted. You see it in the list and can revoke it with **Reject**. It does not re-open a certificate that the store has rejected. Trust decisions made locally on a gateway before 2.0.0 no longer count. Devices with security mode **None** do not use certificates and are not affected. ### Pin a server certificate on a device profile To bind a profile to one server certificate, bring the certificate into the store and choose it. 1. Get the server's certificate file (usually a `.der`, `.cer` or `.pem` file from the server's own certificate folder) and convert it to `.pem`, `.crt` or `.cer` if needed. 2. Select **Upload** and choose the file. It is imported as a public certificate. 3. Select it and select **Trust**. 4. In the device profile's OPC UA connection settings, choose it as the trusted server certificate. See [OPC UA](https://proxus.io/docs/connect/devices/opc-ua). ### Stop trusting a certificate Select it and select **Reject**. Rejected certificates show **Disabled** and are no longer used. Use **Trust View** to list them. ## What's next - [Secure the installation](https://proxus.io/docs/operate/security) - [Back up the hub and the store key](https://proxus.io/docs/operate/backup-and-restore) - [Outbound targets](https://proxus.io/docs/connect/outbound-targets) --- # License > Activate Proxus with a key, read what your license allows, watch each gateway's capacity, and deactivate a license before you move it. Source: https://proxus.io/docs/administer/license At the end of this guide, the hub runs with an active license and you know how much of it each edge gateway uses. ## Before you start - Sign in with a user that has the **Administrators** role. - To activate: a license key from Proxus or your distributor, issued for this installation's **License ID**. > **Tip:** Take a free trial key yourself in the [Proxus portal](https://portal.proxus.io), or see Proxus on your data in a 30-minute session. [Get a free 30-day trial key](/try#licence) · [Book a demo](/demo) ## What a license contains A Proxus license sets these entitlements: | Entitlement | Meaning | | --- | --- | | **Production gateways** | How many edge gateways may run, the hub's own **SYSTEM** gateway included. | | **Capacity tier** | The size of each gateway: how many values per second it may pass on. The tiers and their rates are on [Pricing](/pricing). | | **Sustained data points/sec (per gateway)** | Values per second a gateway may pass on all the time. | | **Burst data points (per gateway, ~3 s)** | A short reserve above the sustained rate, for peaks. | | **White Labeling** | Whether you may show your own title and logo. See [White labeling](https://proxus.io/docs/administer/white-labeling). | The license also has an expiry date. It is checked on the hub against a signature, so checking it needs no internet connection. To ask for a license, a larger tier or an extension, use the [contact form](/contact?topic=evaluation) or ask your distributor. On a network without internet access, see [Install without internet access](https://proxus.io/docs/operate/offline-install#step-5-activate-the-license). ## Activate a license When the hub has no valid license (a new installation, an expired license), the **License Activation** window opens after you sign in. 1. Copy the **License ID** with **Copy** and send it to Proxus or your distributor. The key they send back works only for this ID. For a 30-day trial, take the key yourself: in the [Proxus portal](https://portal.proxus.io), sign in and select **Get a trial licence**. The portal keeps the key, so you can copy or download it again later. 2. Paste the key into **License key**. 3. Tick **I have read and accept the End User License Agreement**. 4. Select **Activate License**. Select **Sign out** to leave the window without activating. > **Note:** The **License ID** is made from the hub's host and its configuration volume. If you move Proxus to another machine, the ID can change and the old key is refused with "This key was issued for another installation". Ask for a new key for the new ID. ## Read your entitlement and live capacity Go to **Platform > License Info**. The window shows the capacity tier and the expiry date at the top. *Screenshot: The License Info window with the License Entitlement table, the Live Capacity table and the Deactivate License button marked* 1. **License Entitlement**: what the license allows. **License status** is **V2** for a current license. 2. **Live Capacity (per gateway)**: for every running gateway, its **Health**, the values per second it passes on now (**Observed dp/s**) against the licensed rate, the burst reserve left, and how many values it accepted and rejected since it started. 3. **Deactivate License** removes the license from this hub. **Health** is **Healthy** below 70 % of the sustained rate, **Warning** from 70 %, **Critical** from 90 %, and **Exceeded** when the gateway has rejected values. **Stale** means the hub has had no report from that gateway recently. Until a gateway reports, the table says it is waiting for the edge gateway heartbeat. ## What happens at the limits | Limit | What Proxus does | | --- | --- | | Number of gateways reached | **New** and **Clone** are not available on the edge gateway list. A gateway above the limit is not started, and a "License limit" warning is logged. | | A gateway reads more than its sustained rate | It uses its burst reserve. When the reserve is empty, it drops the values above the limit. They are counted in **Total rejected**, and **Health** shows **Exceeded**. | | License expired or invalid | The **License Activation** window opens at sign-in with the reason. Users cannot work until a valid key is activated. | | An edge gateway gets no license from the hub | The gateway stops if the hub does not send it a license within five minutes of starting. | > **Warning:** Values dropped above the licensed rate are not stored, published or sent to outbound targets. If **Total rejected** grows, read fewer tags or read them less often, spread devices over more gateways, or ask for a larger capacity tier. ## Deactivate a license Deactivate a license when you retire an installation or move the license to another one. 1. Open **Platform > License Info**. 2. Select **Deactivate License** and confirm with **Deactivate**. The license is removed and you are signed out. Licensed features stop until a license is activated again. ## Manage company licences in the Proxus portal Commercial licences are given to a company in the [Proxus portal](https://portal.proxus.io). Create your company there and invite your colleagues by email. The Proxus team verifies the company and defines the licences you bought. 1. In the portal, choose your company from the workspace menu at the top and select **Licences**. 2. Next to a licence marked **Waiting to be bound**, select **Bind to an installation →**. 3. Paste the hub's **License ID**, give the installation a name and select **Bind and create key**. 4. Copy the key or download the `.lic` file, and activate it on the hub as in [Activate a license](#activate-a-license). To move a licence to a new server, deactivate it on the old hub first. Then, on the licence's page in the portal, enter the new installation's License ID under **Move to another installation**. Three moves a year are included. Owners and admins of the company bind and move licences; members see the licences and download their keys. When Proxus renews a licence or changes its capacity, the new key for the same installation is emailed to the company's owners and admins and shown on the licence's page in the portal. On the hub, deactivate the old license first, then activate the new key. ## What's next - [Watch capacity and health over time](https://proxus.io/docs/operate/monitoring) - [Manage edge gateways](https://proxus.io/docs/connect/edge-gateways/manage-gateways) --- # Set up Copilot > Add the AI service Copilot answers with. Claude, OpenAI, Azure OpenAI, Amazon Bedrock, Google Vertex AI or Ollama, with a key or your cloud identity. Source: https://proxus.io/docs/administer/copilot-settings At the end of this guide, [Copilot](https://proxus.io/docs/monitor/copilot) answers questions with the AI service you chose. You can add more than one service: users then choose which one answers. ## Before you start - An administrator account, or a role with full access to **Copilot settings and usage** (the built-in IT Administrator; the Auditor may only read). See [Users and roles](https://proxus.io/docs/administer/users-and-roles). - An account with one of these services: | Service | Sign-in | What you need | | --- | --- | --- | | **Anthropic Claude** | API key | An API key from the Claude Console. | | **OpenAI** | API key | An API key from the OpenAI platform. | | **Azure OpenAI** | API key, cloud identity or service credential | The resource endpoint (for example `https://plant.openai.azure.com`) and the name of a model deployment. | | **Claude on Amazon Bedrock** | Cloud identity, API key or service credential | An AWS account with access to the Claude models in Amazon Bedrock, and the region. | | **Claude on Google Vertex AI** | Cloud identity or service credential | A Google Cloud project with the Claude models enabled in Vertex AI, and the region. | | **Ollama (local)** | none | An Ollama server the hub can reach, with a model pulled (for example `ollama pull llama3.2`). No data leaves your site. | - For a cloud service, the hub needs outbound HTTPS access to that service. A Claude.ai or ChatGPT subscription cannot be used: Copilot signs in with an API key or with your company's cloud account. API use is billed separately from those subscriptions; add credit in the service's billing settings before you test. ## Choose a sign-in | Sign-in | What is stored | Use it when | | --- | --- | --- | | **API Key** | The key, encrypted. | The service gives you a key. | | **Cloud Identity** | Nothing. | The hub runs in Azure, AWS or Google Cloud with an identity of its own, or its environment has the cloud's credentials. | | **Service Credential** | The secret, encrypted. | The hub runs outside that cloud, with a service identity created for it. | With **Cloud Identity**, the hub uses the identity it runs as: | Service | Where the identity comes from | Permission it needs | | --- | --- | --- | | Azure OpenAI | Managed identity or workload identity, or the `AZURE_TENANT_ID`, `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET` environment variables. Enter **Client ID / Access Key ID** to pick a user-assigned managed identity. | The **Cognitive Services OpenAI User** role on the resource. | | Amazon Bedrock | The IAM role of the host (EC2, ECS, EKS), an AWS profile, or the `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_SESSION_TOKEN` environment variables. | Inference on the Claude models you use. | | Google Vertex AI | The service account attached to the host, or the key file in `GOOGLE_APPLICATION_CREDENTIALS`. | The **Vertex AI User** role in the project. | With **Service Credential**, enter the identity and its secret: | Service | Identity fields | Secret (in **API Key or Secret**) | | --- | --- | --- | | Azure OpenAI | **Tenant ID** and **Client ID / Access Key ID**: the Entra ID app's tenant and client id | The client secret. | | Amazon Bedrock | **Client ID / Access Key ID**: the AWS access key id | The secret access key. | | Google Vertex AI | none | The service account's JSON key, pasted whole. Only service account keys are accepted. | ## Add a service 1. Open **Platform > Copilot Settings** and select **New**. 2. Enter a **Name** that users will recognise, for example `Claude` or `Local model`. 3. Choose the **Service**. Each service shows its logo. **Sign-in** and **Model** are filled in with the usual choice: | Service | Suggested model | | --- | --- | | Anthropic Claude | `claude-opus-5-5` | | OpenAI | `gpt-5` | | Azure OpenAI | none: enter your deployment name | | Claude on Amazon Bedrock | `anthropic.claude-opus-5-5` | | Claude on Google Vertex AI | `claude-opus-5-5` | | Ollama (local) | `llama3.2` | You can pick another model after the connection test below loads the service's list. 4. Fill in the fields the screen shows for that service: **Endpoint** for Azure OpenAI (and for Ollama when the server is not at `http://localhost:11434`; in Docker, use the address of the machine that runs Ollama), **Region** for Amazon Bedrock (for example `eu-central-1`) and Google Vertex AI (for example `europe-west1`), **Project ID** for Google Vertex AI. 5. Choose the **Sign-in** and enter what it needs (see the tables above). 6. Select **Test Connection** (see below) and pick the **Model** from the list. 7. Tick **Default** if this service should answer new conversations. Only one service is the default. 8. Select **Save**. *Screenshot: A Copilot service for Anthropic Claude with the model claude-haiku-5-5, Enabled and Default ticked, prices, currency and monthly budget, and a green Connection result after Test Connection* **API Key Status** shows where the sign-in comes from: **Stored (encrypted)**, the environment variable it uses, or **Uses the hub's cloud identity**. ## Test the connection and choose a model **Test Connection** signs in with the settings on screen, even before you save. It then: 1. loads the models the service offers to this account into the **Model** list; 2. asks the chosen model a one-word question, which costs a few tokens. **Connection** shows the result. It turns green when the model answered, and red with what to fix when something failed: | Message | What to do | | --- | --- | | Sign-in refused | Check the API key, or the identity and its secret. | | This account may not use this model | Give the account access to the model in the service's console. | | The model was not found | Pick a model from the **Model** list. For Azure OpenAI, enter a deployment name. For Ollama, pull the model first. | | No credit or quota left | Add credit in the service's billing settings. | | Too many requests | The service is busy right now. Try again in a minute. | | The service could not be reached | Check the **Endpoint** and the hub's outbound internet access. | | A setting is missing or wrong | Fill in the field it names: **Endpoint**, **Region** or **Project ID**. | | The key contains spaces or line breaks | Copy the key again and paste it. | | This is not a Claude API key | Claude API keys start with `sk-ant-api`. Create one under **API Keys** in the Claude Console. | | This is a Claude Admin API key | An Admin key cannot ask questions. Create a normal API key. | | This is a Claude subscription token | A Claude.ai subscription cannot be used by other applications. Create an API key. | | This is not an OpenAI API key | OpenAI API keys start with `sk-`. Create one under **API keys** on the OpenAI platform. | | The service returned an error | The message gives the service's own reason. | The key checks run before anything is sent, so a wrong key costs nothing. Claude, OpenAI, Azure OpenAI, Ollama and Amazon Bedrock list their models. Google Vertex AI does not, so the list shows the Claude models it usually serves. Before the test, the list offers the usual models of the service (Claude Opus, Sonnet and Haiku 5.5 for the Claude services). Azure OpenAI lists the models of the resource. Its **Model** is the name of your deployment, which you can type. You can still type any model name the service accepts. Changing the service, the sign-in, the key or the model clears the result, so test again before you save. ## How keys and secrets are kept - A key or secret is encrypted with the platform key as soon as you save it, the same key that protects the stored certificates (see [Certificates](https://proxus.io/docs/administer/certificates)). A copy of the database alone does not reveal it. - It is never shown again. The field shows dots, and **API Key Status** shows its last four characters so you can tell keys apart. To replace it, paste a new one and save. Leaving the field as it is keeps the stored one. - With **API Key** sign-in and no key stored, the hub uses the service's environment variable: `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `AZURE_OPENAI_API_KEY` or `AWS_BEARER_TOKEN_BEDROCK`. > **Warning:** The service is used by every user who asks Copilot. Set a usage limit or budget for it in the service's console. ## Decide who may use the Copilot Each role has a **Copilot** tab in **Security > Roles**: | Field | What it does | | --- | --- | | **Copilot Access** | **No access**, **Ask questions** (the default: Copilot reads with the user's permissions) **Ask and propose changes** (Copilot may also prepare changes for the user to approve) or **Ask, propose changes and run actions** (Copilot may also press buttons for the user, such as publishing a pipeline or sending a test message; each still needs its [capability](https://proxus.io/docs/administer/users-and-roles#capabilities) and the user's approval). | | **Copilot Daily Token Limit** | Tokens one member may use per day, counting what is sent and what comes back. New roles start with 200,000; it cannot be 0. The limit resets at midnight (UTC). | A user with several roles gets the most generous access and the highest limit among them. Administrators have every right and no limit. Users whose roles have no access do not see the Copilot button or the Copilot page. To keep a service for some roles only, add them under **Allowed Roles** on the service. A service with no role listed is open to every Copilot user. ## Prices and budget On each service, **Input Price (per 1M tokens)** and **Output Price (per 1M tokens)** take the prices of the service's price list, in **Currency** (USD unless you change it). Copilot then estimates what each answer cost. **Monthly Budget** caps what the service may cost in a calendar month (UTC): - At 80 percent, a **Copilot budget** insight appears in **Monitor > Copilot > Insights** for administrators and the roles that may read **Copilot settings and usage**. At 100 percent it turns critical. - At 100 percent, the service stops answering until the next month. Users can switch to another service they are allowed to use. Leave the budget at 0 for no budget. The estimates come from the prices you entered; the service's own bill is what counts. ## Usage **Platform > Copilot Usage** shows, for this month, the last 30 days or the last 7 days: - the number of answers, the tokens and the estimated cost; - the tokens per day; - the split by AI service, with each service's budget for the month; - the split by user. The records stay when a conversation is deleted. When a service does not report its token counts (some local models), they are estimated from the text and the page says so. Only administrators see this page. *Screenshot: The Copilot Usage page for this month: answers, tokens and estimated cost, tokens per day, and the split by AI service and by user* ## Turn a service off Clear **Enabled** and save. Users can no longer choose it, and conversations that used it are answered by the default service. Deleting a service has the same effect. ## What reaches the AI service For each question, the hub sends the question, the earlier questions and answers of the conversation, and the plant data that Copilot reads to answer it: device names and states, latest tag values, alarms and configuration findings. Only data the asking user may read is sent. With **Ollama (local)**, nothing leaves the site; with Amazon Bedrock, Google Vertex AI and Azure OpenAI, the data stays in your own cloud account. Changes that Copilot proposes are made only when the user approves them, with that user's permissions. See [Changes you approve](https://proxus.io/docs/monitor/copilot#changes-you-approve). Conversations are stored in the hub's database. Administrators can read every conversation in **Monitor > Copilot** with **Show everyone's conversations**. ## What's next - [Copilot](https://proxus.io/docs/monitor/copilot): what Copilot can answer and do, and how changes are approved. - [Users and roles](https://proxus.io/docs/administer/users-and-roles): who may use Copilot. --- # Configuration > Where the hub's configuration file lives, how to change it in the Config Editor, and how environment variables override it. Source: https://proxus.io/docs/administer/configuration At the end of this guide, you have changed a setting of the hub and the hub runs with it. Most of what you set up in Proxus (devices, rules, users) is stored in the database and changes at once. A smaller set of settings that the hub and its gateway need when they start, such as ports, database connections, log levels and password rules, is in one file: `Proxus-config.toml`. ## Before you start - Sign in with a user that has the **Administrators** role. - Plan a short break: a changed setting only takes effect after a restart. - Know which key you want to change. Every key is listed in [Configuration keys](https://proxus.io/docs/reference/configuration). ## Where the file is | Installation | Location | | --- | --- | | Docker (the shipped `docker-compose.yml`) | `/app/config/Proxus-config.toml` inside the `proxus-ui` and `proxus-server` containers. Both use the same `config` volume, so they read the same file. | | Kubernetes | `/app/config/Proxus-config.toml` on the config volume of each pod. The hub and each gateway have their own volume. | | Without containers | Next to the program files of the hub or gateway. | If the file is missing when Proxus starts, Proxus writes a new one with the default values. An upgrade does not replace an existing file. The same folder holds the keys the hub creates for itself, among them `keys/STORE/certificate-store.key`, the key that decrypts the private keys in the [Certificate Store](https://proxus.io/docs/administer/certificates). Back up the whole folder, not only the file. See [Backup and restore](https://proxus.io/docs/operate/backup-and-restore). ## The file in short The file is in TOML: sections in square brackets, then `Key = value` lines. A `#` starts a comment. ```toml [Logging] Loglevel = 3 # 0 Trace, 1 Debug, 2 Information, 3 Warning, 4 Error, 5 Critical LogToFile = true [Security] Lockout.MaxFailedAccessAttempts = 3 ``` The main sections: | Section | What it sets | | --- | --- | | `[Service]` | Ports and addresses of the hub and gateway, the HTTPS ports, and the names the hub's certificates cover. | | `[NATS]` | How the hub and the gateway reach the message broker, and the extra names of its TLS certificate. | | `[Database]`, `[ClickHouse]` | The configuration database and the telemetry database: connection, retention. | | `[Security]`, `[Security.Password]` | Lockout after wrong passwords and password rules. | | `[Rules.DeviceNaming]` | An optional naming rule for device names. | | `[Data]` | Time ranges and limits for lists and logs on screen. | | `[EdgeGateway]` | The gateway's ID, name and mode. | | `[Fieldbus]`, `[Browse]` | How devices are read and discovered. | | `[MQTTBroker]`, `[UNS]` | The built-in MQTT broker (with its TLS port) and the Unified Namespace topics. | | `[ScheduledDelivery]` | Sending reports by email. | | `[Logging]`, `[Metrics]`, `[Tracing]`, `[Otlp]` | Logs, metrics and their export. See [Monitoring](https://proxus.io/docs/operate/monitoring). | | `[MCP]` | Access for AI agents. See [MCP](https://proxus.io/docs/develop/mcp). | ### HTTPS and certificate settings These keys decide how the hub is reached over TLS. Their meaning is in [Configuration keys](https://proxus.io/docs/reference/configuration#service). ```toml [Service] UI-HTTPS-Port = "8443" # empty turns HTTPS off # RedirectHttpToHttps = "false" # "true" sends HTTP to HTTPS and turns on HSTS # PublicHttpsPort = "8443" # the port others reach HTTPS on, if published differently # PublicHostNames = "proxus.plant.example, 203.0.113.10" [NATS] # TlsHostNames = "nats.plant.example" [MQTTBroker] TlsPort = 8883 # 0 turns MQTT over TLS off PlainEnabled = true # false accepts TLS only ``` Add every name and address users or gateways use to reach the hub to `PublicHostNames`. The hub's HTTPS and NATS certificates then cover them. Addresses you choose when you create a gateway install command are added to the NATS certificate automatically. ## Change a setting in the Config Editor 1. Go to **Platform > Config Editor**. The whole file opens as text. 2. Find the key and change its value. 3. Select **Save**. 4. Confirm the warning **Confirm Configuration Changes**. The file is written. 5. Proxus asks **Confirm Platform Restart**. Select **Restart** to restart now, or restart later yourself. *Screenshot: The Config Editor with the top of Proxus-config.toml and the Save and Save and Close buttons marked* 1. **Save** writes the file and keeps the editor open. 2. **Save and Close** writes the file and closes the editor. > **Warning:** The editor does not check the file. A typing error, such as a missing quote, can stop the hub from starting after the restart. Copy the file before a large change (the copy button at the top right of the editor copies the whole text), and change one thing at a time. If the hub no longer starts, correct the file on the volume and start it again. **Restart** restarts the containers of the Docker Compose project named `proxus`, the hub last. It works only on Docker, and only when the stack was started with that project name (see [Docker](https://proxus.io/docs/operate/docker)). Otherwise restart the stack yourself: ```bash docker compose -p proxus restart ``` Every save writes a warning with your user name to the [system logs](https://proxus.io/docs/administer/system-logs). ## To return a key to its default Default values are written in the file as comment lines. Removing a value or turning it back into a comment does not restore the default. Type the default value explicitly, save and restart. ## Environment variables win over the file Each key can also be set as an environment variable. The name is the section and the key joined with two underscores, for example: | In the file | As an environment variable | | --- | --- | | `[Logging]` `Loglevel` | `Logging__Loglevel` | | `[NATS]` `BrokerUrl` | `NATS__BrokerUrl` | | `[Service]` `UI-HTTPS-Port` | `Service__UI-HTTPS-Port` | | `[Service]` `PublicHostNames` | `Service__PublicHostNames` | An environment variable overrides the file. The shipped `docker-compose.yml` already sets some, for example `Logging__Loglevel: "3"` on the hub and `NATS__BrokerUrl` on both containers. A change to these keys in the Config Editor has no effect until you also change or remove the variable in the compose file. One environment variable has no key in the file: `PROXUS_CERTIFICATE_STORE_KEY`. Set it (a base64 value of 32 bytes) to give the Certificate Store its key from outside, for example from a Kubernetes Secret, instead of the file `keys/STORE/certificate-store.key`. Keep it safe: without it, the stored certificates cannot be read. > **Tip:** Keep values that differ per installation, such as passwords and ports, in the compose file or in Kubernetes Secrets, and leave the file at its defaults. An upgrade then never touches your settings. ## What's next - [Every configuration key](https://proxus.io/docs/reference/configuration) - [Secure the installation](https://proxus.io/docs/operate/security) --- # System logs > Find the warnings and errors behind a problem, from the hub and every edge gateway, and set how much Proxus logs and for how long. Source: https://proxus.io/docs/administer/system-logs At the end of this guide, you have found the log entries that explain a problem, such as a device that stopped sending data or a rule that did not fire. The hub and every edge gateway send their warnings and errors to one list, so you do not have to sign in to each machine. ## Before you start - A user whose role may open **Platform > System Logs**. - An idea of when the problem started and where (a gateway, a device, a rule). ## Find the entries Go to **Platform > System Logs**. *Screenshot: The System Logs list searched for Gateway, with the view selector, the Source and Count columns and the Support Bundle button marked* 1. The view selector: **Problems** (warnings, errors and critical entries, the default), **Errors** (errors and critical entries) or **All logs** (every level). 2. **Source** says where the entry comes from: **Platform** for the hub, **Gateway 1** and so on for each edge gateway (by its ID). 3. **Count** is how often the same entry happened. Repeats are shown once, with the time of the latest one. 4. **Support Bundle** packs the logs for Proxus support. See [Support bundle](https://proxus.io/docs/administer/support-bundle). To narrow the list: - Type a device name, tag name, rule name or gateway in **Text to search...** and press Enter. - Use the filter icon in a column header, for example to show one **Level** or one **Source**. **Reason** is a short code for the kind of problem, where Proxus knows one, for example a notification limit that was reached. ## Read an entry The list cuts each message to one line. Select an entry to open it. *Screenshot: A log entry opened from the list: the level, time, source, reason and count on top, the whole message with its Copy button, and the identifiers below* 1. The level, the time of the latest occurrence, the source, the reason and how often it happened. 2. The whole message. **Copy** puts it on the clipboard, for example for a support case. When the entry has a **Diagnostic** (more technical detail, see `IncludeDiagnosticDetails` below), it follows with its own **Copy**. 3. **Identifiers**: the category, event ID, correlation ID, fingerprint and gateway ID of the entry. Proxus support may ask for them. **Close** returns to the list. The list shows the last day by default and at most 1,000 groups of entries; the footer says how many groups are shown. To look further back, change `LogsTimeRange` in the `[Data]` section of the [configuration file](https://proxus.io/docs/administer/configuration), for example `LogsTimeRange = "7d"`. ## How much is logged `Loglevel` in the `[Logging]` section sets the lowest level that is stored: | Value | Level | | --- | --- | | `0` | Trace | | `1` | Debug | | `2` | Information | | `3` | Warning (default) | | `4` | Error | | `5` | Critical | With the default, only warnings and worse are stored, so **All logs** shows the same as **Problems** most of the time. Lower the level only while you look for a problem, then set it back: lower levels write much more. > **Note:** The shipped `docker-compose.yml` sets `Logging__Loglevel: "3"` on the hub container. This environment variable wins over the file. To change the hub's level on Docker, change it in the compose file and recreate the container. Other keys in `[Logging]`: | Key | Default | Meaning | | --- | --- | --- | | `OperationalLogDedupeWindowSeconds` | `60` | The same warning or error within this many seconds is stored once, then every tenth time. Each stored entry carries how many times it happened since the one before, so **Count** in the list is the real number. | | `IncludeDiagnosticDetails` | `false` | When `true`, entries keep more technical detail. Turn it on only for a support case. | | `LogToFile` | `true` | Also write log files on disk (see below). | | `LogSqlQueries` | `false` | Log every database query. Only for support cases: it writes a lot and can contain data. | ## How long logs are kept | Where | Kept for | Set by | | --- | --- | --- | | The **System Logs** list (telemetry database) | 45 days | `ClickHouseLogTTLExpression` in `[ClickHouse]` | | Log files on disk | Until you delete them | One file per day, a new one after each 1 MB | The log files are in the configuration folder (`/app/config` in the containers), named by date, for example `2026-10-15_000.log`. They are part of the `config` volume. Delete old ones from time to time, or keep them small by leaving `Loglevel` at `3`. ## What's next - [Send the logs to Proxus support](https://proxus.io/docs/administer/support-bundle) - [Troubleshoot](https://proxus.io/docs/troubleshoot) - [Monitor the installation](https://proxus.io/docs/operate/monitoring) --- # Audit trail > See the change history of a device, profile, rule, user or any other record. Who changed it, when, which field, and the old and new value. Source: https://proxus.io/docs/administer/audit-trail At the end of this guide, you know who changed a record, when, and what it looked like before. Proxus writes every change to a saved record into its audit trail: a new device, a changed tag address, a deleted rule, a role that got a new permission. ## Before you start - The record you want to check, for example a device profile. - Administrators see every change. Users with the **Default** role see only the changes they made themselves. For other roles, the role needs read access to the audit records. ## Open the change history of a record 1. Open the record, for example **Connect > Device Profiles** and then the profile `Dough mixer`. 2. Select **Audit Trail** in the toolbar. *Screenshot: The Audit Trail window of the device profile Dough mixer, with the newest changes first: time, user, operation, property and old and new values* The window lists every change, newest first: | Column | Meaning | | --- | --- | | **Time** | When the change was saved. | | **User** | Who saved it. | | **Operation** | What happened: an object was created, a field was changed, an item was added to or removed from a list, an object was deleted. | | **Field** | The field that changed. Shown by its caption on screen; no value shows as a dash, a boolean as **Yes** or **No**. | | **Old Value** and **New Value** | The value before and after. | Use **Text to search...** to find a field or a value, and the filter icons in the column headers to show one user or one kind of change. The window is read-only. Select **Close** to leave it. ## Where a change came from With each change, Proxus also records where it came from: - a browser session, with a short session ID, the IP address and the browser and system, for example `Browser session 3f2a9c1b · 10.20.0.31 · Chrome on Windows`; - the REST API (`Web API`), with the IP address. Changes made by AI agents through the [MCP server](https://proxus.io/docs/develop/mcp) arrive this way; - `Background task` for changes Proxus makes by itself. > **Note:** Since 2.0.0, the **Audit Trail** window shows this in its **Source** column. Changes recorded before 2.0.0 have no source. If you saved a column layout for this window earlier, tick **Source** once in the Column Chooser. ## How long changes are kept Audit records are kept until you delete them; there is no setting that removes old ones. They are stored in the configuration database, so they are part of every [database backup](https://proxus.io/docs/operate/backup-and-restore). ## What's next - [Users and roles](https://proxus.io/docs/administer/users-and-roles) - [System logs](https://proxus.io/docs/administer/system-logs) --- # White labeling > Show your own application title and logo in the hub instead of the Proxus brand. Needs a license that includes white labeling. Source: https://proxus.io/docs/administer/white-labeling At the end of this guide, the hub shows your application title in the browser tab and your logo in the header. ## Before you start - A license that includes white labeling. **Platform > License Info** shows **White Labeling** **Yes** in the **License Entitlement** table. Without it, the **White Labeling** menu item is not shown. See [License](https://proxus.io/docs/administer/license). - Sign in with a user that has the **Administrators** role. - Your logo as a PNG file. Other formats are refused with "Only PNG files are allowed for the logo." ## Set your title and logo Go to **Platform > White Labeling**. While nothing is set, the list says **Using the Proxus brand**. *Screenshot: The White Labeling list, empty, with the New and Restore Default buttons marked* 1. **New** creates the setting. Create only one: the hub uses the first one it finds. 2. **Restore Default** returns to the Proxus brand. On the new setting: 1. **App Title**: the name shown in the browser tab, for example `Meridian Plant Data`. 2. **Logo**: upload your PNG. It replaces the Proxus logo in the header. 3. **Custom Css**: optional style rules for the hub's pages, for experienced users. Rules that would hide the About information are removed. 4. Select **Save**, then reload the page in the browser. With white labeling, the Proxus logo is also left out of reports. ## Return to the Proxus brand Open the setting and select **Restore Default**. The title and the style rules are cleared and the Proxus logo comes back. > **Warning:** After the hub's container is replaced, for example by an [upgrade](https://proxus.io/docs/operate/upgrade), the header can show the Proxus logo again although your setting is still saved. Open the setting, upload the logo again and save. ## What's next - [License](https://proxus.io/docs/administer/license) --- # Support bundle > Create a cleaned-up ZIP file of recent logs, runtime details and configuration fingerprints to send to Proxus support. Source: https://proxus.io/docs/administer/support-bundle At the end of this guide, you have a ZIP file that Proxus support can use to analyse a problem. Proxus removes passwords, tokens, connection strings and file paths from it before you download it. ## Before you start - A user whose role may open **Platform > System Logs**. - The time the problem happened, so you can choose a time range that covers it. ## Create the bundle 1. Go to **Platform > System Logs**. 2. Select **Support Bundle** in the toolbar. 3. Set the options and select **Generate**. The browser downloads the file. *Screenshot: The Generate Support Bundle dialog with the time range, the Include File Logs option and the Generate button marked* 1. **Time Range (hours)**: how far back the logs go, from 1 to 168 hours (one week). The default is 24. 2. **Include File Logs** and **Include Operational Logs**: the log files from disk and the entries of the **System Logs** list. Both are ticked by default. **Max Log Files** (1 to 25, default 8) and **Max KB Per File** (64 to 4096, default 512) limit how much of the log files goes in; the newest part of each file is kept. 3. **Generate** builds the file and downloads it. The file is named `proxus-support-bundle-` followed by the date and time in UTC, for example `proxus-support-bundle-20261015-142233.zip`. ## What is in the bundle | File | Contents | | --- | --- | | `manifest.json` | The options you chose. | | `runtime-health.json` | The machine name, the operating system and runtime version, the Proxus version, culture and time zone. | | `config-fingerprint.json` | A few settings in plain text (telemetry database, log level and log options, culture) and a fingerprint of all other settings, so support can see whether the configuration changed without seeing it. | | `file-logs/` | The end of each log file, cleaned up. | | `operational-logs.json` | Up to 500 entries of the **System Logs** list. | Before anything goes into the bundle, Proxus replaces passwords, secrets, API keys, tokens, connection strings, credentials in addresses and absolute file paths with `[redacted]` or `[path]`. Measured values from your machines are not included. > **Note:** The machine name of the hub is included as it is. Open the ZIP file and check it before you send it if your company's rules require that. ## Send the bundle Send the ZIP file to your Proxus partner, or to Proxus support through the [contact form](/contact). Say when the problem started and what you saw, so support can find it in the logs. ## What's next - [System logs](https://proxus.io/docs/administer/system-logs) - [Troubleshoot](https://proxus.io/docs/troubleshoot) --- # Install and operate > Run Proxus with Docker or Kubernetes, upgrade it, back it up, watch its health and secure it. Source: https://proxus.io/docs/operate This section is for the person who runs the Proxus installation itself: the containers, the databases, the network and the backups. To manage users, license and settings inside the hub, see [Administer](https://proxus.io/docs/administer). ## What runs where Proxus is shipped as container images. A hub installation is a small set of services that run together: | Service | What it does | | --- | --- | | `proxus-ui` | The hub: the web interface, the REST API, the MCP server for AI agents, and the coordination of all gateways. | | `proxus-server` | The hub's own edge gateway, called **SYSTEM**. It reads devices on the hub's network and runs the built-in MQTT broker. | | `hub-server` | The message broker (NATS) that connects the hub and every edge gateway. | | `postgresql` | The configuration database: devices, profiles, rules, users, audit trail. | | `clickhouse` | The telemetry database: every value read, and the system logs. | Each edge gateway on a remote network runs as its own small set of containers on its own host. See [Install a gateway](https://proxus.io/docs/connect/edge-gateways/install-a-gateway). For how the parts work together, see [Architecture](https://proxus.io/docs/concepts/architecture). Docker Compose on one machine is the standard way to run Proxus. Kubernetes manifests are provided for sites that run everything on Kubernetes, including a high-availability variant. ## Start here --- # Docker > Run the hub with the shipped docker-compose.yml. What each service and volume holds, which ports it opens, and how to start, stop and adjust it. Source: https://proxus.io/docs/operate/docker At the end of this guide, the Proxus hub runs on one machine with Docker Compose, under a fixed project name, with the time zone and settings of your site. For a first test installation, [Install Proxus](https://proxus.io/docs/get-started/install) is shorter. ## Before you start - A Linux machine (or a Windows or macOS machine with Docker Desktop) that meets the [system requirements](https://proxus.io/docs/get-started/system-requirements). - Docker Engine with the Docker Compose plugin (`docker compose version` prints a version). - The `docker-compose.yml` file for Proxus 2.0.0, in a folder of its own, for example `/opt/proxus`. - Access to Docker Hub, where the images `proxusplatform/proxus-ui` and `proxusplatform/proxus-server` are published, or the images loaded beforehand with `docker load`. See [Install without internet access](https://proxus.io/docs/operate/offline-install). > **Note:** Older Proxus packages also contained a `Deployment/docker-compose.yml` with Redis, a separate API service and TimescaleDB. That file is not used by 2.0.0. Use the `docker-compose.yml` that comes with the release. ## What the compose file runs | Service | Image | Published ports | Data | | --- | --- | --- | --- | | `proxus-ui` (the hub) | `proxusplatform/proxus-ui` | `8443` HTTPS and `8080` HTTP: web interface, REST API, MCP | volumes `config`, `proxus_modules` | | `proxus-server` (gateway **SYSTEM**) | `proxusplatform/proxus-server` | `8083` gateway HTTP, `1883` MQTT, `8883` MQTT over TLS | volume `config` | | `hub-server` (message broker) | `nats` | `4222` clients and `7422` edge gateways (both TLS), `8222` monitoring | volumes `nats`, `config` | | `postgresql` (configuration database) | `postgres:16` | `5442` | volume `proxus-db-volume` | | `clickhouse` (telemetry database) | `bitnamilegacy/clickhouse` | `8123`, `9000`, `9004`, `9005` | volume `clickhouse_data`, folder `./clickhouse-logs` | Every service restarts by itself (`restart: always`) and the hub, the gateway and the databases have health checks. The `config` volume is shared by the hub, the gateway and the broker: it holds the configuration file, the broker's credentials and TLS certificate, the keys that protect sign-ins, and the Certificate Store key (`keys/STORE/certificate-store.key`). Without the Certificate Store key, the certificates in the database cannot be read, so back up the `config` volume together with the database. See [Backup and restore](https://proxus.io/docs/operate/backup-and-restore). The `proxus-ui` container also mounts the Docker socket (`/var/run/docker.sock`). The hub uses it to restart the stack after a configuration change. ## Start the stack Run the stack under the project name `proxus`. The hub's **Restart** button in the [Config Editor](https://proxus.io/docs/administer/configuration) only finds containers of a project with that name, and the volume names in this documentation (`proxus_config` and so on) assume it. ```bash cd /opt/proxus docker compose -p proxus up -d ``` On the first start, the hub creates the message broker's credentials on the `config` volume. Until it has done that, `hub-server` prints "Waiting for Proxus UI to create the NATS trust" every two seconds. This is expected. Check that everything runs: ```bash docker compose -p proxus ps ``` `proxus-ui`, `proxus-server` and `postgresql` show `healthy` once they are ready. Then open `https://:8443` and sign in. HTTPS is on by default, with a certificate from the platform's own certificate authority; `http://:8080` stays available for local access. See [Security](https://proxus.io/docs/operate/security#https). > **Tip:** Naming the folder `proxus` has the same effect as `-p proxus`, because Compose uses the folder name as the project name. Use the same project name every time: the volumes belong to the project, so another name finds none of your data. The containers have fixed names, so only one Proxus hub stack can run on a host. ## Day-to-day commands | Task | Command | | --- | --- | | Stop everything (data stays) | `docker compose -p proxus stop` | | Start again | `docker compose -p proxus start` | | Restart the hub only | `docker compose -p proxus restart proxus-ui` | | Follow a service's output | `docker compose -p proxus logs -f proxus-ui` | | Remove the containers (volumes stay) | `docker compose -p proxus down` | > **Danger:** `docker compose down -v` also deletes the volumes: every device, rule, user and stored value, and the broker credentials that edge gateways need. Never use `-v` on an installation you want to keep. ## Adjust the stack for your site Change these in `docker-compose.yml`, then apply them with `docker compose -p proxus up -d`. Compose recreates only the containers whose settings changed. **Time zone.** The file sets `TZ: Europe/Istanbul` for the hub and the gateway. Log times and times on screen use it. Set it to the time zone of the plant, for example `TZ: Europe/Paris`. **Settings as environment variables.** Any key of the [configuration file](https://proxus.io/docs/administer/configuration) can be set under `environment:` as `Section__Key`. Values set here win over the file and survive upgrades: ```yaml environment: <<: *dotnet-env ASPNETCORE_URLS: http://+:8080 Service__UI-Port: "8080" Logging__Loglevel: "3" NATS__BrokerUrl: nats://hub-server:4222 Security__Lockout__MaxFailedAccessAttempts: "5" ``` **Ports.** To publish the web interface on another port of the host, change only the left side: `"80:8080"`. To keep a port reachable only from the host itself, bind it to the loopback address: `"127.0.0.1:5442:5442"`. The services reach each other on the internal `proxus` network and do not need the published ports. See [Security](https://proxus.io/docs/operate/security) for which ports must be open. **HTTPS.** The hub serves HTTPS on `8443`. To publish it on another host port, for example `"443:8443"`, also set `Service__PublicHttpsPort: "443"`. Add the names users type to reach the hub with `Service__PublicHostNames`, so the hub's certificates cover them. **MQTT over TLS.** The **SYSTEM** gateway's broker also listens for TLS on `8883`, which the shipped file publishes next to `1883`. A file from an earlier version does not: add `"8883:8883"` to the ports of `proxus-server`. **ClickHouse memory.** The `clickhouse` service is limited to 8 GB of memory (`memory: 8g` under `deploy.resources.limits`). Lower it on a small machine, raise it for a large installation. ## After an upgrade to 2.0.0 Restart the message broker once after the hub has started, so it picks up its TLS certificate: ```bash docker restart hub-server ``` Then run the install command of every remote edge gateway again. See [Upgrade](https://proxus.io/docs/operate/upgrade#upgrading-to-200). ## What's next - [Upgrade](https://proxus.io/docs/operate/upgrade) - [Back up the installation](https://proxus.io/docs/operate/backup-and-restore) - [Harden the installation](https://proxus.io/docs/operate/security) - [Install an edge gateway on another host](https://proxus.io/docs/connect/edge-gateways/install-a-gateway) --- # Install without internet access > Install the hub and edge gateways on a network with no internet access. Carry the images over as files, load them, start, and activate the license offline. Source: https://proxus.io/docs/operate/offline-install At the end of this guide, the Proxus hub runs on a machine that cannot reach the internet, its license is active, and edge gateways on the same closed network can be installed. You prepare the files on a machine that has internet access and carry them over, for example on a USB drive. Proxus collects, stores, shows and sends data inside your network without any internet connection. Two things normally come from the internet, and this page replaces both: the installer (from `proxus.io`) and the container images (from Docker Hub). ## Before you start You need: - **A connected machine** with Docker, to download the files. Use one with the same processor type as the target machines (x86-64 or ARM64), or add `--platform`, for example `--platform linux/arm64`, to each `docker pull`. - **The hub machine** on the closed network, with Docker Engine and the Docker Compose plugin already installed, and the [system requirements](https://proxus.io/docs/get-started/system-requirements) met. Docker itself is not part of the Proxus files: install it from your operating system's offline packages first. - A way to carry about 2 to 3 GB of files to the hub machine. - A license key, or a way to send the hub's **License ID** to Proxus or your distributor from another machine (see [Step 5](#step-5-activate-the-license)). ## Step 1: Download the files on the connected machine 1. Download the installer for the hub machine's operating system: ```bash curl -fsSL https://proxus.io/install.sh -o install.sh ``` ```powershell Invoke-WebRequest https://proxus.io/install.ps1 -OutFile install.ps1 ``` If your Proxus delivery came with a prepared `docker-compose.yml`, you can use that file instead of the installer. 2. Download the images the hub uses: ```bash docker pull proxusplatform/proxus-ui:latest docker pull proxusplatform/proxus-server:latest docker pull nats:alpine docker pull postgres:16 docker pull bitnamilegacy/clickhouse:latest ``` These are the images named in the compose file that the installer writes. If you use a compose file from your delivery, `docker compose config --images` in its folder lists the images it needs. 3. Save them into one file: ```bash docker save -o proxus-hub-images.tar \ proxusplatform/proxus-ui:latest proxusplatform/proxus-server:latest \ nats:alpine postgres:16 bitnamilegacy/clickhouse:latest ``` 4. If you will install edge gateways on other machines of the closed network, save their images too. A gateway runs the same `proxus-server` image next to a small message server of its own: ```bash docker pull nats:2-alpine docker save -o proxus-edge-images.tar proxusplatform/proxus-server:latest nats:2-alpine ``` Copy `install.sh` (or `install.ps1`, or your `docker-compose.yml`) and the `.tar` files to the drive. ## Step 2: Load the images on the hub machine Copy the files to the hub machine, then load the images: ```bash docker load -i proxus-hub-images.tar docker image ls ``` `docker image ls` lists the five images with the tags above. Docker Compose uses an image that is already on the machine and downloads nothing. ## Step 3: Start the hub Run the installer you carried over, in the folder where Proxus should live: ```bash bash install.sh ``` ```powershell powershell -ExecutionPolicy Bypass -File .\install.ps1 ``` The installer needs no internet access. It asks for the culture and the time zone, detects the machine's address for edge gateways, and writes `proxus-platform/docker-compose.yml`. Answer `Y` to **Start the platform now?**: the stack starts from the loaded images. With a compose file from your delivery instead, follow [Install from a compose file](https://proxus.io/docs/get-started/install#install-from-a-compose-file). Its `docker compose up -d` also uses the loaded images. Check that every service is running and healthy: ```bash cd proxus-platform docker compose ps ``` ## Step 4: Tell the hub it has no internet access The edge gateway install window offers the hub's public internet address, which the hub looks up on the internet. On a closed network the lookup finds nothing and the list shows only the local addresses. To skip the lookup, add this line under `environment:` of the `proxus-ui` service in `docker-compose.yml`, then run `docker compose up -d`: ```yaml Service__DetectPublicAddress: "false" ``` ## Step 5: Activate the license The license check runs on the hub against the key's signature. Activation does not contact Proxus, so it works the same way on a closed network. 1. Open `https://:8443`, sign in as `Admin` with an empty password, as in [Sign in for the first time](https://proxus.io/docs/get-started/install#sign-in-for-the-first-time). 2. In the **License Activation** window, select **Copy** next to the **License ID** and write it down or save it to a file. 3. From any machine with e-mail or internet access, send the License ID to Proxus or your distributor. The key you get back works only for this ID. 4. Paste the key into **License key**, accept the agreement and select **Activate License**. The License ID comes from the hub's host and its configuration volume. Keep both when you move or restore the hub, or ask for a new key. See [License](https://proxus.io/docs/administer/license). ## Install edge gateways on the closed network An edge gateway needs to reach only the hub, on port `7422` and on the hub's HTTPS port (`8443` by default). 1. On the gateway machine, load the images you saved in Step 1: ```bash docker load -i proxus-edge-images.tar ``` 2. Create the gateway in the hub and run its install command, as in [Install an edge gateway](https://proxus.io/docs/connect/edge-gateways/install-a-gateway). The command comes from the hub, so it works without internet access. When the image cannot be downloaded, the installer uses the images already on the machine and continues. To take the gateway image from a registry on your own network instead, set `EdgeDeployment__Image` on the `proxus-ui` service to the image's full name in that registry, for example `registry.plant.local/proxusplatform/proxus-server:latest`. The install command then uses that name. ## What needs the internet, and what to use instead | Feature | Without internet access | | --- | --- | | Install, upgrade | Carry the images over as on this page. | | License | Works. Only the License ID and the key travel, by any channel you choose. | | Copilot | Use **Ollama (local)** on a machine of your network. Cloud AI services cannot be reached. Copilot's documentation search ships with the hub and works offline. See [Copilot settings](https://proxus.io/docs/administer/copilot-settings). | | Outbound targets | A target on your network works. A cloud target works only if the gateway that sends to it can reach it. For AWS IoT Core, choose Amazon Root CA 1 together with the certificates: the hub cannot download it itself. See [Secure connections to targets](https://proxus.io/docs/connect/secure-target-connections). | | Notification channels | E-mail works with a mail server on your network. Services on the internet, such as Slack, Teams or Telegram, cannot be reached. | | Documentation | This site needs the internet. The hub's own copy of the documentation, used by Copilot, does not. | ## Upgrade without internet access Repeat Step 1 for the new release on the connected machine, then on the hub machine: ```bash docker load -i proxus-hub-images.tar cd proxus-platform docker compose up -d ``` Loading replaces the `latest` images, and Compose recreates the containers whose image changed. Read [Upgrade](https://proxus.io/docs/operate/upgrade) first: it says what to back up and what to do after each release. On each gateway machine, load the new edge images and recreate the gateway in its folder, skipping the `pull` step of [Upgrade the edge gateways](https://proxus.io/docs/operate/upgrade#upgrade-the-edge-gateways): ```bash docker load -i proxus-edge-images.tar cd /opt/proxus/proxus-edge-3 sudo docker compose -p proxus-edge-3 -f compose.yaml up -d ``` ## What's next - [Harden the installation](https://proxus.io/docs/operate/security) before you connect the plant network. - [Back up the installation](https://proxus.io/docs/operate/backup-and-restore), including the `config` volume. - [Run Proxus with Docker](https://proxus.io/docs/operate/docker) for the day-to-day commands. --- # Kubernetes > Deploy Proxus on Kubernetes with the shipped manifests: local, high-availability and data variants, what high availability covers, and how to apply them. Source: https://proxus.io/docs/operate/kubernetes At the end of this guide, Proxus runs on your Kubernetes cluster, either as a single copy for tests or as a high-availability (HA) installation. Docker Compose remains the standard way to run Proxus; use Kubernetes when your site runs its workloads there. ## Before you start - A Kubernetes cluster and `kubectl` with access to it. - The `Deployment/kubernetes` folder of the Proxus 2.0.0 release. - For HA: at least three nodes, a storage class that offers `ReadWriteMany` volumes, the NGINX ingress controller, and the two database operators named below. ## The variants | Folder | What it deploys | Namespace | | --- | --- | --- | | `local/` | One of each service, like the Docker Compose stack. Not HA. For tests and development. | `proxus` | | `ha/` | The HA application: two hub replicas, a three-node message broker cluster, one pod per gateway, Secrets, disruption budgets and an ingress. | `proxus-ha` | | `ha-data/` | HA databases for `ha/`: a three-instance PostgreSQL cluster (CloudNativePG) and a two-replica ClickHouse cluster with a three-node Keeper (Altinity operator). | `proxus-data`, `clickhouse` | | `nats-trust/` | Shared by the others: creates the message broker's credentials and TLS certificate once and publishes them as a Secret. | (included) | > **Warning:** Always apply a folder with `kubectl apply -k `. The manifests take their namespace from the folder's `kustomization.yaml`; `kubectl apply -f` on a single file puts the resources in the wrong namespace. ## What high availability means for Proxus | Part | In `ha/` | What happens when a pod or node fails | | --- | --- | --- | | Hub (`proxus-ui`) | 2 replicas, active-active, behind an ingress with sticky sessions | The other replica keeps serving. Users of the failed replica are moved to the other one and may have to sign in again. | | Message broker (`hub-server`) | 3-node cluster, every stream kept on all three (`NATS__Replicas=3`). The servers connect to each other by pod name over TLS (port `6222`). | No message is lost when one broker pod fails. | | Gateway (`proxus-server-gateway-1`) | Exactly 1 pod, `Recreate` | Kubernetes restarts the pod. Reading pauses until it is back. | | PostgreSQL | 3 instances, managed by CloudNativePG | The operator promotes a replica. | | ClickHouse | 2 replicas with a 3-node Keeper | The other replica answers. | A gateway is never run as two copies: two pods with the same gateway ID would read the same devices twice. Do not set `replicas` above 1 on a gateway deployment. High availability for a gateway means a fast restart, not a second running copy. ## Try it with `local/` ```bash kubectl apply -k Deployment/kubernetes/local kubectl -n proxus get pods,svc,pvc kubectl -n proxus port-forward svc/proxus-ui 8080:8080 ``` Then open `http://localhost:8080`. On the first start, `hub-server` and `proxus-server` stay in `ContainerCreating` until the hub has created the broker credentials Secret `proxus-nats-trust`. This is expected. The hub serves HTTPS on port `8443` as well. The local variant has the database passwords in the manifests and keeps one copy of everything. Do not use it in production. To remove it, including its volumes: ```bash kubectl delete -k Deployment/kubernetes/local ``` ## Deploy the HA variant 1. Install the two database operators, CloudNativePG and the Altinity ClickHouse operator, following their own instructions. The README in `Deployment/kubernetes` names the versions that were tested. 2. Set your database passwords. In `ha/secrets.yaml`, change `user`, `password` and `database` of the Secret `postgres-credentials`; they are all `proxus` in the shipped file. Use the same values for the PostgreSQL cluster in `ha-data/`, and change the ClickHouse credentials there too. 3. Check the storage. In `ha/storage.yaml`, the hub's shared volumes (`proxus-ui-config-rwx`, `proxus-ui-modules-rwx`, `nats-hub-config`) must be `ReadWriteMany` on a storage class that supports it before the hub replicas run on different nodes. 4. Set the host name. In `ha/ingress-nginx-sticky.yaml`, replace `proxus.local` with your DNS name and add a `tls` section with your certificate Secret. Keep the cookie affinity annotations: they keep each browser on one hub replica. 5. If you use managed or existing databases instead of `ha-data/`, point the two ExternalName services in `ha/external-data-services.yaml` at them. Then apply the data layer, then the application: ```bash kubectl apply -k Deployment/kubernetes/ha-data kubectl apply -k Deployment/kubernetes/ha ``` Check that everything runs: ```bash kubectl -n proxus-ha get pods,pdb,svc ``` Two `proxus-ui` pods, three `hub-server` pods and one `proxus-server-gateway-1` pod should be `Running`. The broker credentials and the broker's TLS certificate (Secret `proxus-nats-trust`) are created by the hub on its first start. Every connection to the broker uses TLS and checks the server against the platform CA. The hub renews the certificate before it expires. Do not write or edit that Secret by hand. The Certificate Store key is kept in `keys/STORE/certificate-store.key` on the hub's shared config disk (`proxus-ui-config-rwx`). Back it up with that disk, or give it to the hub from your own Secret with the environment variable `PROXUS_CERTIFICATE_STORE_KEY` (a base64 value of 32 bytes). See [Certificates](https://proxus.io/docs/administer/certificates#protect-the-stores-private-keys). > **Note:** The manifests refer to images tagged `latest-arm64`. On nodes of another processor architecture, set the image tags to the matching Proxus images, for example with an `images:` entry in your own kustomization that uses the shipped folder as its base. ## Connect edge gateways from outside the cluster Remote edge gateways connect to the message broker on port `7422`. In the shipped manifests, the `hub-server` service is only reachable inside the cluster. Expose port `7422` to the networks of your gateways, for example with a `LoadBalancer` service, and use that address when you [install a gateway](https://proxus.io/docs/connect/edge-gateways/install-a-gateway). The broker's certificate covers every address an install command is created for. If gateways reach the broker under another name, add it to `[NATS]` `TlsHostNames` or `[Service]` `PublicHostNames`. ## Limits of the current manifests - ClickHouse credentials in `ha-data/` are written in the manifest, not in a Secret. - There is no NetworkPolicy. Add one if your cluster requires default-deny. - The hub does not get the Docker socket on Kubernetes, so the **Restart** button of the Config Editor has no effect. Restart with `kubectl -n proxus-ha rollout restart deployment/proxus-ui`. - After an upgrade to 2.0.0, restart the `hub-server` pods once after the hub has started (`kubectl -n proxus-ha rollout restart statefulset/hub-server`), then run every remote gateway's install command again. See [Upgrade](https://proxus.io/docs/operate/upgrade#upgrading-to-200). - Back up the config volumes of the hub and of each gateway. See [Backup and restore](https://proxus.io/docs/operate/backup-and-restore). ## What's next - [Upgrade](https://proxus.io/docs/operate/upgrade) - [Monitoring](https://proxus.io/docs/operate/monitoring) - [Security](https://proxus.io/docs/operate/security) --- # Upgrade > Move a Proxus installation to a new release. Back up, pull the new images, let the hub update its database, then upgrade the edge gateways. Source: https://proxus.io/docs/operate/upgrade At the end of this guide, the hub and its edge gateways run the new release, with all devices, rules, users and stored values kept. You do not run database scripts yourself: the hub updates its own database. ## Before you start - A backup made just before the upgrade. See [Backup and restore](https://proxus.io/docs/operate/backup-and-restore). There is no way back to the old release without it. - The release notes of the new version. - A maintenance window. Devices are not read while the gateways restart. ## What changes and what stays | Part | During an upgrade | | --- | --- | | Container images | Replaced by the new ones. | | Configuration database | Kept. The hub adds what the new release needs (new tables and columns) the first time it connects to the database. | | Telemetry database | Kept. | | `Proxus-config.toml` | Kept as it is. Keys that are new in the release use their default value until you add them. | | Environment variables in your compose file or manifests | Kept. | ## Upgrading to 2.0.0 Release 2.0.0 turns on TLS for every connection of the platform, with certificates from the [Certificate Store](https://proxus.io/docs/administer/certificates). Plan these extra steps around the normal upgrade below. **Before the upgrade** 1. Make the backup as usual. The config folder (the `config` volume, or the hub's shared config disk on Kubernetes) now also holds `keys/STORE/certificate-store.key`, the key that decrypts the certificates in the store. It is created on the first start of 2.0.0, so include the config folder in every backup from then on. If you set `PROXUS_CERTIFICATE_STORE_KEY` instead, keep that value safe. 2. Open the new ports in your firewall: `8443` (the hub's HTTPS, on by default) on the hub host, and `8883` (MQTT over TLS) on edge gateway hosts where devices publish to the gateway's broker. **After the hub has started** 3. Restart the hub's NATS server once, so it starts with TLS: - Docker: `docker restart hub-server` - Kubernetes: restart the `hub-server` pods, for example `kubectl -n proxus-ha rollout restart statefulset/hub-server` (namespace `proxus` for the local variant). 4. Run the install command of every edge gateway again: **Connect > Edge Gateways**, open the gateway, select **Install**, and run the new command on its host. Gateways installed before 2.0.0 cannot connect to the hub until then. They keep reading their devices and buffer the data (48 hours by default), and send it once they are connected. See [Install a gateway](https://proxus.io/docs/connect/edge-gateways/install-a-gateway). 5. If you want browsers to trust the hub's HTTPS certificate, renew the old one: in **Security > Certificate Store**, select **Proxus (Self-Signed)** and select **Renew**. The new certificate is issued by the platform CA and covers the hub's names. Then install the platform CA on users' computers (**Download CA**). See [Certificates](https://proxus.io/docs/administer/certificates#the-hubs-https-certificate). **Check the connections that are now verified** 6. OPC UA: devices that use the security modes **Sign** or **SignAndEncrypt** send no data until their server's certificate is trusted in the store. Open **Security > Certificate Store**, set **Trust View** to **Rejected**, and select **Trust** for each server you recognise. Devices connect on their next retry. Devices with security mode **None** are not affected. 7. Outbound targets: a target that connects to a server with a self-signed certificate or a certificate from a private CA (for example your own MQTT broker, Splunk or an AWS IoT endpoint) worked before because nothing was checked. Upload the server's CA to the Certificate Store and choose it as the target's **Trusted Server Certificate**. Otherwise the connection is refused. See [Outbound targets](https://proxus.io/docs/connect/outbound-targets). **Where things moved** - **Users**, **Roles** and **Certificate Store** are now in the new **Security** menu, between **Analyze** and **Platform**. **My Details** stays under **Platform**. ## Upgrade a Docker installation ### 1. Back up and keep the current images Make the backup. Then keep a copy of the images you run now, so you can go back: ```bash docker image tag proxusplatform/proxus-ui:latest proxusplatform/proxus-ui:before-upgrade docker image tag proxusplatform/proxus-server:latest proxusplatform/proxus-server:before-upgrade ``` ### 2. Download the new images ```bash cd /opt/proxus docker compose -p proxus pull ``` If the host has no internet access, load the images you received with `docker load -i ` instead. See [Install without internet access](https://proxus.io/docs/operate/offline-install#upgrade-without-internet-access). ### 3. Recreate the containers ```bash docker compose -p proxus up -d ``` Compose replaces only the containers whose image changed. The volumes stay. ### 4. Sign in and check 1. Open the hub in the browser and sign in. The hub checks the database against the new release and updates it. This can take a while on a large database; do not stop the container meanwhile. 2. Check the version at the bottom of the menu (**Version:**) and look at **Platform > System Logs** for errors. If the database update fails, the hub shows an error instead of the sign-in page and writes the reason to its output. Keep the message (`docker compose -p proxus logs proxus-ui`) and contact Proxus support. To go back, tag the `before-upgrade` images as `latest` again (`docker image tag proxusplatform/proxus-ui:before-upgrade proxusplatform/proxus-ui:latest`, and the same for `proxus-server`), restore the backup and start the stack. > **Warning:** The shipped compose file uses the `latest` tag. Every `pull` gets the newest release, also when you only meant to recreate a container or move to a new machine. Pull only when you plan to upgrade. ## Upgrade a Kubernetes installation The manifests use `imagePullPolicy: IfNotPresent` with a fixed tag, so a node that already has the image does not download a new one by itself. 1. Make the backup, including the config volumes. 2. Set the new image tag in your kustomization (an `images:` entry), or set `imagePullPolicy: Always`. 3. Apply and restart, as below. 4. Sign in and check the version and the system logs as for Docker. ```bash kubectl apply -k Deployment/kubernetes/ha kubectl -n proxus-ha rollout restart deployment/proxus-ui deployment/proxus-server-gateway-1 ``` The hub replicas are replaced one at a time, so the web interface stays available. The gateway pod is stopped and started again. ## Upgrade the edge gateways The hub's own gateway, **SYSTEM**, is part of the stack above and is upgraded with it. Upgrade every remote edge gateway right after the hub, so hub and gateways run the same release. On each gateway host, the installer put the gateway in `/opt/proxus/proxus-edge-`, where `` is the gateway's ID. Pull and recreate it there: ```bash cd /opt/proxus/proxus-edge-3 sudo docker compose -p proxus-edge-3 -f compose.yaml pull sudo docker compose -p proxus-edge-3 -f compose.yaml up -d ``` Instead, you can create a new install command for the gateway in the hub and run it on the host again. It replaces the containers and gives the gateway new credentials; the old ones stop working. See [Install a gateway](https://proxus.io/docs/connect/edge-gateways/install-a-gateway). Check on **Connect > Edge Gateways** that every gateway shows **Connected** again. > **Warning:** When you upgrade from a release before 2.0.0, pulling the new image is not enough: the gateway also needs the new TLS settings of the install command. Run a new install command on each gateway host, as described in [Upgrading to 2.0.0](#upgrading-to-200). ## After the upgrade - If you use [white labeling](https://proxus.io/docs/administer/white-labeling), check that your logo is shown; upload it again if not. - Read the release notes for new configuration keys you may want to set. ## What's next - [Backup and restore](https://proxus.io/docs/operate/backup-and-restore) - [Monitoring](https://proxus.io/docs/operate/monitoring) --- # Backup and restore > Proxus has no built-in backup. What to back up in the Docker stack, how to make a consistent copy of its volumes, and how to restore it. Source: https://proxus.io/docs/operate/backup-and-restore At the end of this guide, you have a copy of everything a Proxus hub needs to start again with all its devices, rules, users, stored values and gateway connections, and you know how to restore it. > **Warning:** Proxus does not make backups by itself. There is no backup button and no scheduled backup in the product. Set up the backup described here, or your company's own volume or database backup, and test a restore. ## Before you start - The hub runs with the shipped `docker-compose.yml` under the project name `proxus` (see [Docker](https://proxus.io/docs/operate/docker)). With another project name, the volume names start with that name instead of `proxus_`. - A backup location outside the hub's machine, with room for the telemetry database. - Shell access to the host with permission to run `docker`. ## What to back up All data of the stack is in five Docker volumes: | Volume | Contains | If you lose it | | --- | --- | --- | | `proxus_config` | `Proxus-config.toml`, the message broker's credentials and TLS files (`nats/`), the keys that protect sign-ins (`keys/`), the Certificate Store key (`keys/STORE/certificate-store.key`), OPC UA certificates of the gateway, log files | Every remote edge gateway must be installed again, every user is signed out, the configuration is back to defaults, and the certificates in the database cannot be read. | | `proxus_proxus-db-volume` | The configuration database (PostgreSQL): devices, profiles, tags, rules, pipelines, users, roles, certificates, license, audit trail | Everything you set up in the hub. | | `proxus_clickhouse_data` | The telemetry database (ClickHouse): every stored value and the system logs | All history: trends, reports, logs. | | `proxus_nats` | Messages waiting in the broker, and broker account data | Messages not yet delivered. | | `proxus_proxus_modules` | Add-on modules installed in the hub | Add-ons must be installed again. | Also keep a copy of your `docker-compose.yml` with your changes. > **Danger:** The `config` volume and the configuration database belong together. Back them up at the same time and restore them together. The broker credentials in `config` are what every edge gateway trusts: without them, all remote gateways must be enrolled again. The Certificate Store key in `config` decrypts the private keys stored in the database: without it, every certificate (the platform CA, the hub's HTTPS and NATS certificates, the gateways' certificates, outbound target certificates) has to be created or uploaded again. Check the exact volume names on your host: ```bash docker volume ls --filter name=proxus_ ``` If you give the hub its Certificate Store key with the environment variable `PROXUS_CERTIFICATE_STORE_KEY` instead of the file, keep that value with your backups. ## Make a full backup (stack stopped) A copy of the volumes while the stack is stopped is consistent: the databases are not writing. Devices are not read while the stack is stopped, so plan it outside production hours, for example every night or every week. ```bash BACKUP=/backup/proxus/$(date +%F) mkdir -p "$BACKUP" cp /opt/proxus/docker-compose.yml "$BACKUP/" docker compose -p proxus stop for v in config proxus-db-volume clickhouse_data nats proxus_modules; do docker run --rm -v proxus_$v:/data:ro -v "$BACKUP":/backup alpine \ tar czf /backup/$v.tar.gz -C /data . done docker compose -p proxus start ``` Copy the folder to your backup location and keep several generations. ## Back up the configuration database while running To keep the configuration safe between full backups without stopping anything, dump the configuration database and copy the `config` volume. Run it daily, or before a large change: ```bash BACKUP=/backup/proxus/$(date +%F-%H%M) mkdir -p "$BACKUP" docker exec postgresql pg_dump -U proxus -p 5442 -d proxus -Fc > "$BACKUP/proxus-db.dump" docker run --rm -v proxus_config:/data:ro -v "$BACKUP":/backup alpine \ tar czf /backup/config.tar.gz -C /data . ``` This does not include stored values. Use the full backup for those. If you changed the database user, password or name in your compose file, use your values instead of `proxus`. ## Restore on the same machine Stop the stack, replace the contents of each volume with the backup (here from a full backup in `$BACKUP`), and start the stack again: ```bash docker compose -p proxus stop for v in config proxus-db-volume clickhouse_data nats proxus_modules; do docker run --rm -v proxus_$v:/data -v "$BACKUP":/backup alpine \ sh -c "find /data -mindepth 1 -delete && tar xzf /backup/$v.tar.gz -C /data" done docker compose -p proxus start ``` Then sign in and check devices, trends and users. To restore only the configuration database from a `pg_dump` file, stop the hub and the gateway, restore, and start them again: ```bash docker compose -p proxus stop proxus-ui proxus-server docker exec -i postgresql pg_restore -U proxus -p 5442 -d proxus --clean --if-exists < "$BACKUP/proxus-db.dump" docker compose -p proxus start proxus-ui proxus-server ``` ## Restore on a new machine 1. Install Docker and copy the backed-up `docker-compose.yml` to `/opt/proxus`. 2. Create the containers and volumes without starting them: `docker compose -p proxus create` in `/opt/proxus`. 3. Fill the empty volumes with the `for` loop above (without the `stop`), then start with `docker compose -p proxus start`. 4. If the new machine has another address, change the address the edge gateways use to reach the hub (port `7422`) in your DNS, or install the gateways again. The hub's certificates cover the machine's names and addresses: add the address the gateways and users use to `[Service]` `PublicHostNames`, restart, and renew the hub's HTTPS certificate in **Security > Certificate Store** if browsers report a name mismatch. 5. Sign in. If the license is refused because the **License ID** changed, ask for a new key. See [License](https://proxus.io/docs/administer/license). ## Kubernetes On Kubernetes, back up the persistent volumes of the hub and of each gateway (their `/app/config`) with your cluster's volume backup, and use the backup features of the database operators (CloudNativePG for PostgreSQL, the ClickHouse operator) for the databases. The same rule applies: restore the hub's config volume (with the Certificate Store key) and the configuration database from the same point in time. ## Test the restore A backup you have never restored is a hope, not a backup. Restore to a test machine from time to time, sign in and check that devices, trends and users are there. ## What's next - [Upgrade](https://proxus.io/docs/operate/upgrade) - [Security](https://proxus.io/docs/operate/security) --- # Monitoring the installation > Watch a Proxus installation from outside and inside. Health checks, Prometheus and OpenTelemetry metrics, logs, database health and licensed capacity. Source: https://proxus.io/docs/operate/monitoring At the end of this guide, your monitoring system knows when the hub or a gateway stops answering, and you know where to look for disk space, data volume and licensed capacity before they become a problem. ## Before you start - The hub runs (see [Docker](https://proxus.io/docs/operate/docker) or [Kubernetes](https://proxus.io/docs/operate/kubernetes)). - For metrics: a Prometheus server or an OpenTelemetry collector that can reach the hub and the gateway. ## What to watch | Question | Where to look | | --- | --- | | Does the hub or a gateway answer? | The health check `/healthz` | | Are devices sending data? Are there alarms? | **Monitor > Operations Center** | | Is a gateway near its licensed capacity? Did it drop values? | **Platform > License Info**, **Live Capacity** | | Is the disk filling up? How large is the history? | **Platform > Database Health** | | What went wrong? | **Platform > System Logs** | | Request rates, response times, runtime figures | Prometheus or OpenTelemetry metrics | ## Health checks The hub and every gateway answer `GET /healthz` with the plain text `Healthy` (HTTP 200) when they run, and with `Unhealthy` (HTTP 503) when their internal runtime is not working. | Component | Address | | --- | --- | | Hub | `http://:8080/healthz` | | Gateway (SYSTEM and remote gateways) | `http://:8083/healthz` | ```bash curl -s http://proxus.lyonfoods.local:8080/healthz Healthy ``` The shipped compose file uses these checks for the containers' health status, and the Kubernetes manifests use them as startup, readiness and liveness probes. Point your uptime monitoring or load balancer at them. A healthy answer means the service runs; it does not say that every device is connected. For that, use the Operations Center or the **Live Capacity** table. ## Capacity and dropped values **Platform > License Info** shows, for every running gateway, how many values per second it passes on and how close it is to its licensed rate. Each gateway reports this every few seconds. *Screenshot: The Live Capacity table with the Health, Observed dp/s and Total rejected columns marked for two gateways* 1. **Health**: **Healthy**, **Warning** (70 % of the licensed rate or more), **Critical** (90 % or more), **Exceeded** (values were dropped) or **Stale** (no report from the gateway). 2. **Observed dp/s**: values per second now, and the share of the licensed rate. 3. **Total rejected**: values dropped because the gateway was over its licensed rate. Anything above `0` means data is missing. See [License](https://proxus.io/docs/administer/license#what-happens-at-the-limits). ## Disk and database size **Platform > Database Health** reports on the telemetry database when you open it. *Screenshot: The Database Health report with the Database Summary and Disk Volume tables marked* 1. **Database Summary**: the size of the stored values on disk, their size before compression, and the space saved. 2. **Disk Volume**: the disk the telemetry database writes to, with its free space and **Disk Usage**. Further down, **Table Storage** lists the largest tables and **Retention Policy** shows how long each kind of data is kept. Check the free space regularly: when the disk is full, new values can no longer be stored. The log files on the `config` volume are not deleted by Proxus. Include that volume in your disk checks. See [System logs](https://proxus.io/docs/administer/system-logs#how-long-logs-are-kept). ## Metrics for Prometheus and OpenTelemetry Metrics are off by default. To turn them on, set in the [configuration file](https://proxus.io/docs/administer/configuration): ```toml [Metrics] Enable = true [Otlp] Endpoint = "http://otel-collector:4317" MetricsIntervalMilliseconds = 10_000 SkipWhenEndpointUnresolvable = true ``` Restart the stack. Then: - The hub and the gateway serve Prometheus metrics at `/metrics` on their HTTP ports (`http://:8080/metrics`, `http://:8083/metrics`). Add both as scrape targets. - If `[Otlp]` `Endpoint` points at an OpenTelemetry collector that can be resolved, the same metrics are also pushed there every `MetricsIntervalMilliseconds`. When the address cannot be resolved at start, Proxus does not send to it (`SkipWhenEndpointUnresolvable = true`), so a missing collector cannot slow the gateway down. The metrics cover incoming and outgoing HTTP requests and the internal processing of the hub and gateway. Values per device and capacity are not metrics; use the screens above for those. `[Tracing]` `Enable = true` also sends traces to the OTLP endpoint. Turn it on only while you investigate a problem. > **Note:** `/metrics` needs no sign-in. Make sure only your monitoring system can reach ports `8080`, `8443` and `8083`, or keep metrics off. See [Security](https://proxus.io/docs/operate/security). ## The message broker The broker (`hub-server`) has its own monitoring port, `8222`, with the broker's standard status pages, for example `http://:8222/varz` (server) and `http://:8222/jsz` (stored streams). In the Kubernetes HA variant, each broker pod also serves Prometheus metrics on port `7777` through the service `hub-server-metrics`. ## Logs - **Platform > System Logs** collects warnings and errors from the hub and every gateway. See [System logs](https://proxus.io/docs/administer/system-logs). - The container output: `docker compose -p proxus logs -f proxus-ui` (or `proxus-server`, `hub-server`, `postgresql`, `clickhouse`). ## What's next - [Troubleshoot](https://proxus.io/docs/troubleshoot) - [Security](https://proxus.io/docs/operate/security) --- # Security > Harden a Proxus installation. What is encrypted, network ports to open and to close, HTTPS, default credentials, gateway trust, MCP access and a checklist. Source: https://proxus.io/docs/operate/security At the end of this guide, your Proxus installation has no default passwords left, only the ports it needs are reachable, and users reach the hub over HTTPS. Work through the [checklist](#hardening-checklist) before the hub is used in production, and again after every move to a new machine. ## Before you start - The hub runs with Docker (see [Docker](https://proxus.io/docs/operate/docker)) or Kubernetes. - You can sign in as **Admin**, edit `docker-compose.yml` and the [configuration file](https://proxus.io/docs/administer/configuration), and change the host's firewall. - A [backup](https://proxus.io/docs/operate/backup-and-restore). Several steps below change credentials. ## What is encrypted Proxus 2.0.0 uses TLS on every connection it opens or accepts, with certificates from the [Certificate Store](https://proxus.io/docs/administer/certificates). The store is the platform's own certificate authority (**Proxus Platform CA**), or your corporate CA if you choose one. | Connection | Protection | | --- | --- | | Browsers and API clients to the hub | HTTPS on port `8443`, on by default. HTTP on `8080` stays for local access. See [HTTPS](#https). | | Hub processes and edge gateways to the hub's NATS server | TLS on every port: `4222`, `7422` and, on Kubernetes HA, `6222`. Every connection checks the server against the platform CA. | | Gateway install command | Downloaded over HTTPS and pinned to the hub's HTTPS key, so the script and the gateway's identity cannot be swapped on the way. See [Install a gateway](https://proxus.io/docs/connect/edge-gateways/install-a-gateway). | | MQTT devices and subscribers to a gateway's broker | TLS on port `8883` with the gateway's own certificate. Port `1883` stays for devices without TLS. See [MQTT broker](#mqtt-broker). | | Gateways to outbound targets | The server is always verified: its name must match the address and its certificate must chain to a trusted root. See [Outbound targets](https://proxus.io/docs/connect/outbound-targets). | | Gateways to OPC UA servers | Only servers whose certificate is trusted in the Certificate Store. See [Certificates](https://proxus.io/docs/administer/certificates#trust-or-reject-an-opc-ua-server-certificate). | The private keys of all these certificates are stored encrypted. The key that decrypts them is in the config folder (`keys/STORE/certificate-store.key`) or in the environment variable `PROXUS_CERTIFICATE_STORE_KEY`. Back it up with the config folder. Users, roles and the Certificate Store are in the **Security** menu. ## Network ports Ports of the shipped compose stack on the hub's host: | Port | Service | Who needs to reach it | | --- | --- | --- | | `8443` (TCP) | Hub over HTTPS: web interface, REST API, MCP server, gateway install commands | Users, API clients, AI agents, gateway hosts during installation | | `8080` (TCP) | Hub over HTTP | Local access only, or a reverse proxy. Close it to other machines once everyone uses HTTPS. | | `7422` (TCP, TLS) | Message broker, connections from edge gateways | Every remote edge gateway host | | `1883` (TCP) | MQTT broker of the **SYSTEM** gateway, without TLS | Only MQTT clients and devices that publish to Proxus and cannot use TLS | | `8083` (TCP) | **SYSTEM** gateway: health check, HTTP telemetry input, metrics | Only devices that send data over HTTP, and your monitoring | | `4222` (TCP, TLS) | Message broker, client port | Nobody outside the host. The hub and the SYSTEM gateway use it inside the compose network. | | `8222` (TCP) | Message broker monitoring | Only your monitoring, or nobody | | `5442` (TCP) | PostgreSQL | Nobody outside the host | | `8123`, `9000`, `9004`, `9005` (TCP) | ClickHouse | Nobody outside the host | An edge gateway host only connects out to the hub on port `7422` (and `8443` while it is installed). It accepts connections on `8883`, `1883` and `8083` only if devices on its network publish to it. The shipped compose file publishes `8883` for the **SYSTEM** gateway, so devices on the hub's network can use MQTT over TLS without changes. The shipped compose file publishes all of these ports on every network interface. Close the ones that nobody outside the host needs: either in the host firewall, or by binding them to the loopback address in `docker-compose.yml`, for example `"127.0.0.1:5442:5442"`. The services reach each other over the internal compose network, so this does not affect Proxus. A complete list of ports and endpoints is in [Ports](https://proxus.io/docs/reference/ports). ## HTTPS The hub serves HTTPS on port `8443` by default, with TLS 1.2 or 1.3 and the default certificate of the [Certificate Store](https://proxus.io/docs/administer/certificates). On a new installation this certificate is issued by the platform CA and covers the machine's name, its IP addresses, `localhost` and the names in `[Service]` `PublicHostNames`. Browsers trust it once the platform CA is installed on users' computers (**Download CA** in the Certificate Store), or when your corporate CA signs the platform's certificates. 1. Add every name and address users type to reach the hub to `PublicHostNames`, for example `PublicHostNames = "proxus.lyonfoods.local, 203.0.113.10"`. 2. On an upgraded installation, renew the hub's old self-signed certificate: in **Security > Certificate Store**, select **Proxus (Self-Signed)** and select **Renew**. 3. Install the platform CA on users' computers, or [use your corporate CA](https://proxus.io/docs/administer/certificates#use-your-corporate-ca). These `[Service]` keys control HTTPS: | Key | Default | What it does | | --- | --- | --- | | `UI-HTTPS-Port` | `"8443"` | The HTTPS port. An empty value turns HTTPS off. | | `RedirectHttpToHttps` | `"false"` | `"true"` sends every HTTP request to HTTPS and turns on HSTS. | | `PublicHttpsPort` | not set | The port others reach HTTPS on, when it is published on another port of the host. | | `PublicHostNames` | not set | Extra names and addresses for the hub's certificates, separated by commas. | HTTP on `8080` stays on for local access. `RedirectHttpToHttps` is off by default because HSTS makes browsers use HTTPS for every port of the host, including other services on the same machine. Turn it on when the hub has the host to itself. The shipped compose file publishes `8443`. If you publish HTTPS on another port of the host, for example `"443:8443"`, set `PublicHttpsPort = "443"` so the hub knows the port others reach it on. To publish the hub on the internet under your own domain with a certificate you already have, directly or behind Cloudflare, follow [Serve the hub on your domain](https://proxus.io/docs/operate/custom-domain). **On a reverse proxy.** You can also let your company's reverse proxy or load balancer handle TLS and forward to the hub. The web interface keeps a live connection open, so the proxy must allow WebSocket connections and long timeouts (the Kubernetes ingress uses one hour). Then publish the hub's ports only to the proxy. ## Default credentials to change | Credential | Shipped value | How to change it | | --- | --- | --- | | Hub user **Admin** | Empty password | Sign in as **Admin**, **Platform > My Profile**, **Change My Password**. | | Hub user **APIAdmin** (only on hubs upgraded from an earlier version) | A fixed password, the same in every installation | Open it on **Security > Users** and use **Reset Password**, or clear **Is Active** if you do not use it. Until then the hub writes a warning to **System Logs** at every start. | | PostgreSQL | User, password and database `proxus` | Before the first start: `POSTGRES_PASSWORD` in the compose file and the password in `[Database]` `ConnectionString`. On a running installation, change the password in the database first (`ALTER USER`), then in the connection string. | | ClickHouse | User `admin`, password `proxus` | `CLICKHOUSE_ADMIN_PASSWORD` and the health check in the compose file, and `ClickHousePassword` in `[ClickHouse]`. Plan this change; Proxus cannot store values while the passwords differ. | API tokens are valid for one year by default (`TokenExpireTime = "1y"`). Shorten this if your policy requires it. Database passwords set through `POSTGRES_PASSWORD` take effect only when the database volume is created. Keep the database ports closed (see above) so the database is not reachable even with the default password. ## Edge gateway trust Edge gateways and the hub talk through the message broker over TLS, without shared passwords: - On the first start, the hub creates the broker's root credentials on the `config` volume (folder `nats/`). Only the hub reads them. - When you install a gateway, the gateway host creates its own key and sends only the public part. The hub signs it with permissions for that one gateway. The resulting credentials work only for a gateway connection on port `7422`; a copy cannot be used as a normal broker client. - The gateway's link to the hub is encrypted and checked against the platform CA. Each gateway also gets its own certificate from the Certificate Store for its HTTPS port and its MQTT broker. A gateway can only get its own. - An install link is valid for one use and one hour, and the install command is pinned to the hub's HTTPS key. - Removing or reinstalling a gateway revokes its old credentials at once. Protect the `config` volume like a password store, and include it in every backup. It also holds the Certificate Store key. See [Install a gateway](https://proxus.io/docs/connect/edge-gateways/install-a-gateway). ## MQTT broker The **SYSTEM** gateway's MQTT broker refuses clients without credentials (`[MQTTBroker]` `AllowAnonymous = false`). Keep it that way. Every gateway's broker also accepts MQTT over TLS on port `8883`, with the gateway's own certificate. Devices check the broker against the platform CA (**Download CA** in the Certificate Store), and the host name they connect to must be in the gateway's certificate. Once all devices use TLS, set `[MQTTBroker]` `PlainEnabled = false` so the broker accepts TLS only. `TlsPort = 0` turns TLS off. If you set a `MasterToken`, use a long random value and treat it like a password. The [UNS permissions](https://proxus.io/docs/administer/uns-permissions) of roles do not apply to MQTT clients. See [MQTT](https://proxus.io/docs/develop/mqtt). ## MCP access for AI agents The MCP server at `/mcp` on the hub lets AI agents read and change Proxus data with a user's permissions. Each agent signs in as a Proxus user and can do only what that user's roles allow. The `[MCP]` section adds limits: | Key | Shipped value | Recommendation | | --- | --- | --- | | `Enabled` | `true` | Set `false` if you do not use AI agents. | | `AdminOnly` | `false` | `true` lets only users of an administrative role use MCP. | | `AllowedMethods` | `"GET,POST,PATCH,PUT"` | `"GET"` for agents that may only read. | | `BlockDelete` | `true` | Keep. | | `IPWhitelist` | `[]` (all addresses) | List the addresses of your agent hosts, for example `["10.20.0.0/24"]`. | | `ServerBaseUrl` | `""` | Set to the hub's external address, for example `"https://proxus.lyonfoods.local:8443"`, when agents connect from other machines. | | `AnonymousDiscoveryMode` | `"ToolsAndOverview"` | `"Disabled"` hides the tool list from clients that have not signed in. | | `AuditLogging` | `true` | Keep. | Give each agent its own Proxus user with a role made for it, and limit that role with [UNS permissions](https://proxus.io/docs/administer/uns-permissions). For the full setup, see [MCP](https://proxus.io/docs/develop/mcp). ## Hardening checklist - **Admin** has a strong password. On an upgraded hub, **APIAdmin** has a new password or is disabled. - The shared configuration folder, which holds the key that signs API tokens, is readable only by the people who run the hub. - Every person has their own user. Nobody works as **Admin** day to day. - Roles start from **Deny all by default** and give only what is needed. See [Users and roles](https://proxus.io/docs/administer/users-and-roles). - Password rules in `[Security.Password]` match your policy, and new users have **Force Password Change** ticked. - Account lockout is on (`[Security]` `Lockout.Enabled = true`). - The REST API signing key is a new random value. - PostgreSQL and ClickHouse passwords are changed, or their ports are reachable only from the host. - Only `8443`, `7422` and, where needed, `8883`, `1883` and `8083` are reachable from other machines. - Users reach the hub over HTTPS, and the platform CA (or your corporate CA) is trusted on their computers. - The Certificate Store key (`keys/STORE/certificate-store.key`, or `PROXUS_CERTIFICATE_STORE_KEY`) is backed up with the config folder. - MQTT devices use port `8883`, and `PlainEnabled = false` once none needs `1883`. - MCP is off, or limited by `AdminOnly`, `AllowedMethods` and `IPWhitelist`. - Metrics are off, or ports `8080`/`8443` and `8083` are reachable only by your monitoring. - The `config` volume and the databases are backed up, and the backups are stored away from the host. - Only administrators can reach the host: the hub container can control Docker through the mounted Docker socket. ## What's next - [Users and roles](https://proxus.io/docs/administer/users-and-roles) - [Certificates](https://proxus.io/docs/administer/certificates) - [Monitoring](https://proxus.io/docs/operate/monitoring) --- # Serve the hub on your domain > Publish the hub on the internet under your own domain name over HTTPS, with a certificate you already have, directly or behind Cloudflare. Source: https://proxus.io/docs/operate/custom-domain At the end of this guide, users open the hub at `https://proxus.example.com` from anywhere, with a certificate you already have: one from Cloudflare, your certificate authority or another provider. Plain HTTP sends users to HTTPS, and only the ports that need to be reachable are open. ## Before you start - The hub runs on a server with a public IP address, installed with the [installer or the compose file](https://proxus.io/docs/get-started/install). - **Admin** has a strong password. Do this before the hub is reachable from the internet: see [Security](https://proxus.io/docs/operate/security#default-credentials-to-change). - You can change the DNS records of your domain. - You have the certificate for the hub's name and its private key, in PEM (`.pem`, `.crt`, `.key`) or as a `.pfx`. The certificate must cover the name users type, for example `proxus.example.com` or `*.example.com`. The steps use `proxus.example.com`. Replace it with your own name. ## Step 1: Point the name at the server At your DNS provider, add an `A` record for `proxus.example.com` with the server's public IP address. If you use Cloudflare's proxy, also read [Behind the Cloudflare proxy](#behind-the-cloudflare-proxy) before you continue. ## Step 2: Open only the ports that are needed In your cloud provider's firewall (security group, network security group or firewall rule), allow: | Port | For | | --- | --- | | `443` (TCP) | Users, API clients and the install command of edge gateways. | | `80` (TCP) | Only to send users who type `http://` to HTTPS. | | `7422` (TCP) | Edge gateways on other networks. Leave it closed if every gateway is on the server's own network. | Keep every other port closed to the internet. > **Warning:** Ports published by Docker bypass `ufw` and other host firewalls that manage `iptables`: a port closed in `ufw` is still open if `docker-compose.yml` publishes it. Close ports in the cloud provider's firewall, or bind them to the loopback address in `docker-compose.yml`, as in step 5. ## Step 3: Upload the certificate 1. Sign in to the hub and open **Security > Certificate Store**. 2. Select **Upload** and choose the certificate and its private key together. If your provider gave you a chain or a CA file, choose it too. Proxus finds out which file is which: the certificate that matches the key is stored with it. 3. Check the new row: **Type** is **Server** and the expiry date is the one your provider gave. ## Step 4: Make it the hub's HTTPS certificate Select the uploaded certificate, select **Set as Default** and confirm. The hub serves the new certificate within a minute, without a restart. Nobody is signed out. **Set as Default** is available only for a server certificate with its private key. ## Step 5: Publish the hub on 443 Open `docker-compose.yml` in the `proxus-platform` folder and change the `proxus-ui` service: ```yaml proxus-ui: ports: ["80:8080", "443:8443"] environment: # …the existing entries stay… Service__PublicHttpsPort: "443" Service__PublicHostNames: "proxus.example.com" Service__RedirectHttpToHttps: "true" ``` | Setting | What it does | | --- | --- | | `"80:8080"`, `"443:8443"` | Publishes the hub's HTTP and HTTPS on the standard ports. | | `Service__PublicHttpsPort` | The port users reach HTTPS on. Redirects and edge install commands use it. | | `Service__PublicHostNames` | The hub's name. It is added to the certificates the hub issues itself, for example for its message server. | | `Service__RedirectHttpToHttps` | Sends every HTTP request to HTTPS and turns on HSTS. The container's health check is not redirected. | To keep the databases and the message server off the internet, bind their ports to the loopback address in the same file. The services reach each other over the internal network, so Proxus is not affected: ```yaml hub-server: ports: ["127.0.0.1:4222:4222", "127.0.0.1:8222:8222", "7422:7422"] postgresql: ports: ["127.0.0.1:5442:5442"] clickhouse: ports: ["127.0.0.1:8123:8123", "127.0.0.1:9000:9000", "127.0.0.1:9005:9005", "127.0.0.1:9004:9004"] ``` Apply the changes: ```bash docker compose up -d ``` ## Step 6: Check it 1. Open `https://proxus.example.com`. The browser shows the site as secure and the sign-in page appears. 2. Open `http://proxus.example.com`. The browser goes to `https://proxus.example.com`. 3. Check the certificate the hub sends from any machine: ```bash openssl s_client -connect proxus.example.com:443 -servername proxus.example.com Origin Server** and select **Create Certificate**. Keep the key type **RSA (2048)** and the host names `proxus.example.com` (or `*.example.com`). Save the **Origin Certificate** as `origin.pem` and the **Private Key** as `origin.key`. Cloudflare shows the private key only once. 2. Upload both files as in step 3 and make the certificate the default as in step 4. 3. In **SSL/TLS > Overview**, set the encryption mode to **Full (strict)**. 4. In **Network**, check that **WebSockets** is on. The hub's web interface keeps a live connection open. 5. Publish the hub as in step 5. > **Warning:** Do not use the **Flexible** encryption mode. Cloudflare then connects to the hub over HTTP, the hub sends it to HTTPS, and the browser shows "too many redirects". **Edge gateways cannot connect through the Cloudflare proxy.** The install command checks the hub's own HTTPS key, which the proxy hides behind Cloudflare's certificate, and the gateways' message connection on port `7422` is not HTTP. Give the gateways a name that is not proxied: 1. Add a second `A` record, for example `edge.example.com`, with the same IP address and the proxy **off** (grey cloud). 2. Add the name to `Service__PublicHostNames`, for example `"proxus.example.com, edge.example.com"`, and run `docker compose up -d`. 3. When you install a gateway, choose **Another address** in the install wizard and enter `edge.example.com`. ## Install edge gateways The install wizard offers the addresses it knows; choose the name the gateway's machine can reach the hub on. The command it gives connects to `https://:443` and checks the key of the certificate you made the default, so it works with your own certificate. The gateway then connects to port `7422`. See [Install a gateway](https://proxus.io/docs/connect/edge-gateways/install-a-gateway). An install command is valid for one hour and only until the hub restarts. If you changed `docker-compose.yml` after creating it, create a new one. ## Renew the certificate Proxus does not renew a certificate it did not issue. Before yours expires: 1. Get the new certificate from your provider. 2. Upload it and select **Set as Default**, as in steps 3 and 4. The hub warns in the [system logs](https://proxus.io/docs/administer/system-logs) every day for a certificate that expires within 30 days. A Cloudflare Origin Certificate is valid for up to 15 years. Gateways keep working after the certificate changes: they connect to the hub's message server, which uses its own certificate. Install commands created before the change stop working; create new ones. ## When something does not work | What you see | Cause | What to do | | --- | --- | --- | | The browser warns that the certificate is not valid for the name. | The certificate does not cover the name in the address bar. | Upload a certificate for that name and make it the default. | | The browser still shows the old certificate. | The hub picks up the new default within a minute. | Wait a minute and reload. | | "Too many redirects" behind Cloudflare. | Cloudflare's encryption mode is **Flexible**. | Set it to **Full (strict)**. | | `http://` opens an address with `:8443`. | `Service__PublicHttpsPort` is missing. | Set it to `"443"` and run `docker compose up -d`. | | The edge gateway install says the link is not valid. | The link expired, was used, or the hub restarted. | Create a new command in the install wizard. | | The install command fails with a key or connection error behind Cloudflare. | The command goes through the proxy. | Use a name that is not proxied, see [Behind the Cloudflare proxy](#behind-the-cloudflare-proxy). | ## What's next - [Security](https://proxus.io/docs/operate/security): HTTPS settings, ports and the hardening checklist. - [Certificate Store](https://proxus.io/docs/administer/certificates): certificates on a new installation, renewing and replacing. - [Install a gateway](https://proxus.io/docs/connect/edge-gateways/install-a-gateway): the install wizard step by step. --- # Develop > Build on Proxus. Read and change its data over HTTP, subscribe to live values over MQTT, write C# functions and connect AI agents. Source: https://proxus.io/docs/develop Proxus has several ways in for your own code. Each one serves a different job, so pick by what you want to do, not by the technology you know best. ## Which interface to use | You want to | Use | Runs on | | --- | --- | --- | | List, create or change devices, profiles, rules, targets and other settings from a script | [REST API](https://proxus.io/docs/develop/rest-api) (OData) | hub, port 8443 (HTTPS; 8080 for local access) | | Read stored tag values for a report, a notebook or another system | [Telemetry API](https://proxus.io/docs/develop/telemetry-api) | hub, port 8443 (HTTPS; 8080 for local access) | | Receive live tag values the moment they are read | [MQTT and the UNS topics](https://proxus.io/docs/develop/mqtt) | each edge gateway, port 8883 (TLS; 1883 without) | | Calculate, filter or enrich values inside Proxus, poll a web service, raise your own alarms | [Functions SDK](https://proxus.io/docs/develop/functions-sdk) (C#) | edge gateway | | Load values recorded before the device was connected | [Historical import](https://proxus.io/docs/develop/historical-import) | edge gateway, port 8083 | | Let an AI assistant read the plant model and live state | [MCP server](https://proxus.io/docs/develop/mcp) | hub, `/mcp` | ## How they fit together Everything you do through the hub's interfaces runs as a Proxus user. The same roles and permissions that apply in the hub's screens apply to your code, so create a user with only the rights the integration needs. See [Users and roles](https://proxus.io/docs/administer/users-and-roles). ## Start here --- # REST API > Sign in with a user name and password, get a token, and read or change Proxus objects such as devices, gateways and rules over OData. Source: https://proxus.io/docs/develop/rest-api At the end of this guide, a script of yours signs in to the hub, gets a token and reads devices with their gateway. The same API can create, change and delete objects, within the rights of the user you sign in with. ## Before you start You need: - The hub's address, for example `http://localhost:8080` on a local installation. The API is served on the same port as the hub's screens. - A Proxus user for the integration. Its role decides what the API may read and change, exactly as in the screens. See [Users and roles](https://proxus.io/docs/administer/users-and-roles). - `curl`, Python 3 with the `requests` package, or .NET, depending on the example you follow. ## What the API offers | Address | What it does | | --- | --- | | `POST /api/Authentication/Authenticate` | Checks a user name and password and returns a token. | | `/api/odata/` | Read, create, change and delete objects (OData v4). | | `/api/odata/$metadata` | The full data model: every entity set, its fields and its links. | | `/swagger` | An interactive page that lists every operation and lets you try it. | | `POST /api/Telemetry/execute` | Stored tag values. See [Telemetry API](https://proxus.io/docs/develop/telemetry-api). | Among the entity sets are `Device`, `DeviceProfile`, `DeviceProfileRegister` (tags), `Gateway`, `TargetProfile` (outbound targets), `NotificationChannel`, `Rule`, `RuleAction`, `Flow` (pipelines), `Function`, `Alert`, `Log`, `ScheduledDelivery`, `TrendView` and `UnsTopicPermission`. The list at `/api/odata/` is always the complete one. ## Step 1: Get a token Send the user name and password as JSON. The answer is the token itself, as plain text. ```bash curl -X POST http://localhost:8080/api/Authentication/Authenticate \ -H "Content-Type: application/json" \ -d '{"userName":"Admin","password":""}' ``` Put the token in the `Authorization` header of every later call: ```text Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` - A wrong user name or password returns `401` with the text `User name or password is incorrect.` - A call to `/api/...` without a valid token is answered with `401`, and a call the user may not make with `403`. - A token stays valid for the time set in `TokenExpireTime` (one year in the delivered configuration). Get a new one when a call answers `401`. > **Warning:** Tokens are signed with a key that the hub makes for itself on its first start and keeps in the shared configuration folder (`Keys/UI/jwt-signing.key`). Anyone who has that file can create valid tokens: protect the folder like a password. Set your own key in `IssuerSigningKey` only if another system must check the tokens. See [Configuration keys](https://proxus.io/docs/reference/configuration#webapi). ## Step 2: Read objects ```bash TOKEN=$(curl -s -X POST http://localhost:8080/api/Authentication/Authenticate \ -H "Content-Type: application/json" -d '{"userName":"Admin","password":""}') curl -s -G http://localhost:8080/api/odata/Device \ -H "Authorization: Bearer $TOKEN" \ --data-urlencode "\$filter=startswith(DeviceName,'LYS')" \ --data-urlencode "\$select=Oid,DeviceName,Enabled" \ --data-urlencode "\$count=true" \ --data-urlencode "\$top=3" ``` The answer: ```json { "@odata.context": "http://localhost:8080/api/odata/$metadata#Device(Oid,DeviceName,Enabled)", "@odata.count": 14, "value": [ { "Oid": 66, "DeviceName": "LYS_MILL_01", "Enabled": true }, { "Oid": 67, "DeviceName": "LYS_LINE1_PLC", "Enabled": true }, { "Oid": 69, "DeviceName": "LYS_PACKER_04", "Enabled": true } ] } ``` The usual OData query options work: | Option | Example | Notes | | --- | --- | --- | | `$filter` | `Site eq 'Lyon Foods Plant'` | `eq`, `ne`, `gt`, `lt`, `and`, `or`, `startswith`, `contains` | | `$select` | `Oid,DeviceName,Status` | Only these fields. | | `$expand` | `Gateway($select=Name)` | Follow a link to another object. | | `$orderby` | `DeviceName desc` | | | `$top`, `$skip` | `$top=50&$skip=100` | `$top` may be at most 100. A larger value is refused with `400`. | | `$count` | `$count=true` | Adds `@odata.count` with the total. | > **Warning:** Without `$top`, a query returns every matching object in one answer. On large sets, such as `Log` or `DeviceProfileRegister`, page with `$top` and `$skip` and keep `$select` short. One object is read by its key: `GET /api/odata/Device(69)`. A device's latest values come with it when you expand `LatestValues`: ```bash curl -s -G "http://localhost:8080/api/odata/Device(69)" -H "Authorization: Bearer $TOKEN" \ --data-urlencode "\$select=DeviceName" --data-urlencode "\$expand=LatestValues" ``` Each latest value has `Key`, `Value`, `DataType`, `Quality` and `LastUpdate`. ## Step 3: Use it from code ```python import requests HUB = "http://localhost:8080" # 1. Sign in and get a token response = requests.post( f"{HUB}/api/Authentication/Authenticate", json={"userName": "Admin", "password": ""}, timeout=30, ) response.raise_for_status() token = response.text.strip() headers = {"Authorization": f"Bearer {token}"} # 2. Read the devices of one site with their gateway response = requests.get( f"{HUB}/api/odata/Device", params={ "$filter": "Site eq 'Lyon Foods Plant'", "$select": "Oid,DeviceName,Status", "$expand": "Gateway($select=Name)", "$orderby": "DeviceName", }, headers=headers, timeout=30, ) response.raise_for_status() for device in response.json()["value"]: print(device["Oid"], device["DeviceName"], device["Status"], device["Gateway"]["Name"]) ``` ```csharp using System.Net.Http.Headers; using System.Net.Http.Json; using System.Text.Json; var hub = new HttpClient { BaseAddress = new Uri("http://localhost:8080/") }; // 1. Sign in and get a token var login = await hub.PostAsJsonAsync("api/Authentication/Authenticate", new { userName = "Admin", password = "" }); login.EnsureSuccessStatusCode(); var token = await login.Content.ReadAsStringAsync(); hub.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); // 2. Read the gateways using var gateways = JsonDocument.Parse( await hub.GetStringAsync("api/odata/Gateway?$select=Oid,Name")); foreach (var gateway in gateways.RootElement.GetProperty("value").EnumerateArray()) Console.WriteLine($"{gateway.GetProperty("Oid")} {gateway.GetProperty("Name")}"); ``` ## Create, change and delete The entity sets also take `POST` (create), `PATCH` (change some fields), `PUT` (replace) and `DELETE`, the standard OData way. For example, to switch a device off: ```bash curl -X PATCH "http://localhost:8080/api/odata/Device(69)" \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{"Enabled": false}' ``` The user's role decides what is allowed. A change the role does not permit is refused, exactly as the same change would be refused in the hub's screens. > **Tip:** Open `http://:8080/swagger`, select **Authorize** and paste a token. Every operation of every entity set is listed there with its fields, and you can try calls from the browser. ## What's next - [Telemetry API](https://proxus.io/docs/develop/telemetry-api): stored tag values, with SQL. - [MQTT and the UNS topics](https://proxus.io/docs/develop/mqtt): live values as they are read. - [Network ports and endpoints](https://proxus.io/docs/reference/ports): every address the hub and gateways listen on. --- # Telemetry API > Query the tag values stored in the Proxus historian over HTTP with a single SQL SELECT, and read the rows back as JSON lines. Source: https://proxus.io/docs/develop/telemetry-api At the end of this guide, your script runs a SQL query against the stored tag values of a device and reads the result, one JSON object per row. ## Before you start You need: - A token from the hub, as described in [REST API](https://proxus.io/docs/develop/rest-api#step-1-get-a-token). - The hub's address, for example `http://localhost:8080`. - A hub that stores telemetry in ClickHouse, the database in the delivered Docker installation (`TelemetryDB = "clickhouse"` in the `[Database]` section of the configuration). > **Warning:** The Telemetry API runs the SQL you send, so it cannot apply a user's Unified Namespace permissions. Only users with an administrator role may call it; others get `403`. Give this access only to systems you trust. Users without it read values through the screens, which apply [UNS permissions](https://proxus.io/docs/administer/uns-permissions). ## The request ```text POST /api/Telemetry/execute?maxRows=10000 Authorization: Bearer Content-Type: application/json { "query": "SELECT ..." } ``` | Part | Meaning | | --- | --- | | `query` | One SQL statement, in ClickHouse SQL. | | `maxRows` | The most rows to return, from 1 to 50000. Default 10000. A `LIMIT` in your query is lowered to this value when it is higher; a query without `LIMIT` gets one. | The answer has the content type `application/x-ndjson`: one JSON object per line, one line per row. If the query does not end with a `FORMAT` clause, `FORMAT JSONEachRow` is added for you. ## The table of stored values Every value Proxus stores is one row in `DeviceRawData`: | Column | Type | Meaning | | --- | --- | --- | | `Time` | `DateTime64(3)` | When the value was read, in UTC, to the millisecond. | | `DeviceId` | `UInt32` | The device's ID (the `Oid` of the device in the [REST API](https://proxus.io/docs/develop/rest-api)). | | `DeviceName` | `String` | The device's name at the time of reading. | | `Key` | `String` | The tag name. | | `DataType` | `Enum8` | `Bool`, `Short`, `UShort`, `Int`, `UInt`, `Float`, `Long`, `ULong`, `Double`, `String`, `Byte`, `DateTime`. | | `Unit` | `String` | The tag's unit, empty when it has none. | | `NumericValue` | `Float64` | The value of numeric and Boolean tags. | | `StringValue` | `String` | The value of text tags. | Rows are sorted by device, name, tag and time, so a filter on `DeviceId` or `DeviceName`, `Key` and a time range is the fast way to read them. ## Step 1: Run a query ```bash TOKEN=$(curl -s -X POST http://localhost:8080/api/Authentication/Authenticate \ -H "Content-Type: application/json" -d '{"userName":"Admin","password":""}') curl -s -X POST "http://localhost:8080/api/Telemetry/execute?maxRows=100" \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d "{\"query\": \"SELECT DeviceName, Key, round(avg(NumericValue), 2) AS avg_value, count() AS samples FROM DeviceRawData WHERE Time >= now() - INTERVAL 1 HOUR AND DeviceName = 'LYS_PACKER_04' GROUP BY DeviceName, Key ORDER BY Key\"}" ``` The answer: ```json {"DeviceName":"LYS_PACKER_04","Key":"BatchCount","avg_value":1522.98,"samples":"2262"} {"DeviceName":"LYS_PACKER_04","Key":"MotorCurrent","avg_value":28.91,"samples":"2262"} {"DeviceName":"LYS_PACKER_04","Key":"Speed","avg_value":81.68,"samples":"2262"} {"DeviceName":"LYS_PACKER_04","Key":"Temperature","avg_value":24.64,"samples":"2262"} {"DeviceName":"LYS_PACKER_04","Key":"Vibration","avg_value":1.85,"samples":"2262"} ``` > **Note:** 64-bit integers, such as the result of `count()`, arrive as strings (`"2262"`), so that no digits are lost in JSON. Convert them in your code, or cast them in SQL (`toUInt32(count())`). ## Step 2: Use it from code ```python import json import requests HUB = "http://localhost:8080" token = requests.post( f"{HUB}/api/Authentication/Authenticate", json={"userName": "Admin", "password": ""}, timeout=30, ).text.strip() sql = """ SELECT Key, round(avg(NumericValue), 2) AS avg_value, max(NumericValue) AS max_value FROM DeviceRawData WHERE DeviceName = 'LYS_PACKER_04' AND Time >= now() - INTERVAL 1 HOUR GROUP BY Key ORDER BY Key """ response = requests.post( f"{HUB}/api/Telemetry/execute", params={"maxRows": 1000}, json={"query": sql}, headers={"Authorization": f"Bearer {token}"}, timeout=60, ) response.raise_for_status() for line in response.text.splitlines(): row = json.loads(line) print(row["Key"], row["avg_value"], row["max_value"]) ``` ```csharp using System.Net.Http.Headers; using System.Net.Http.Json; using System.Text.Json; var hub = new HttpClient { BaseAddress = new Uri("http://localhost:8080/") }; var login = await hub.PostAsJsonAsync("api/Authentication/Authenticate", new { userName = "Admin", password = "" }); login.EnsureSuccessStatusCode(); hub.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", await login.Content.ReadAsStringAsync()); // The latest value of each tag of one device var query = new { query = """ SELECT Key, argMax(NumericValue, Time) AS last_value, max(Time) AS last_time FROM DeviceRawData WHERE DeviceName = 'LYS_PACKER_04' AND Time >= now() - INTERVAL 1 HOUR GROUP BY Key ORDER BY Key """ }; var response = await hub.PostAsJsonAsync("api/Telemetry/execute?maxRows=100", query); response.EnsureSuccessStatusCode(); foreach (var line in (await response.Content.ReadAsStringAsync()).Split('\n', StringSplitOptions.RemoveEmptyEntries)) { using var row = JsonDocument.Parse(line); Console.WriteLine($"{row.RootElement.GetProperty("Key")} = {row.RootElement.GetProperty("last_value")}"); } ``` ## Read a long time range One call returns at most 50000 rows. To read more, page by time: sort by `Time` and `DeviceId`, remember the last row, and start the next query after it. ```sql SELECT Time, DeviceId, Key, NumericValue FROM DeviceRawData WHERE DeviceName = 'LYS_PACKER_04' AND Time >= toDateTime64('2026-10-01 00:00:00', 3) AND Time < toDateTime64('2026-10-02 00:00:00', 3) AND (Time > toDateTime64('2026-10-01 06:12:40.250', 3) OR (Time = toDateTime64('2026-10-01 06:12:40.250', 3) AND DeviceId > 69)) ORDER BY Time ASC, DeviceId ASC LIMIT 50000 ``` Stop when a page returns fewer rows than you asked for. ## What the API refuses The query is checked before it reaches the database. These answers come back with status `400`: | Message | Cause | | --- | --- | | `Query cannot be empty` | No `query` in the body. | | `Invalid query: Only SELECT/CTE (WITH), comments, or 'SET TIMEZONE' are allowed at the beginning.` | The statement starts with something else, such as `SHOW` or `DESCRIBE`. | | `Invalid query: Multiple statements are not allowed.` | More than one statement, separated by `;`. | | `Invalid query: After CTEs, only a SELECT statement is allowed.` | A `WITH` block followed by anything but `SELECT`. | | `Invalid query: Security violation: The SQL keyword 'SYSTEM' is not permitted.` | The query contains a word that changes data or the server: `UPDATE`, `DELETE`, `INSERT`, `MERGE`, `UPSERT`, `DROP`, `CREATE`, `ALTER`, `TRUNCATE`, `RENAME`, `ATTACH`, `DETACH`, `OPTIMIZE`, `SYSTEM`, `KILL`, `GRANT`, `REVOKE`, `COPY`, `CALL`, `EXEC`, `EXECUTE`. The check also applies to names, so `system.tables` is refused. Words inside quotes are ignored. | Other answers: | Status | Meaning | | --- | --- | | `401` | No token, or the token has expired. | | `403` | The user does not have an administrator role. | | Status of the database, with `Query failed: ...` | The database refused the query, for example a misspelled column or table. The text is the database's own message. | | `500` with `ClickHouse connection failed: ...` | The hub cannot reach the telemetry database. See [Troubleshoot data](https://proxus.io/docs/troubleshoot/data). | ## What's next - [MQTT and the UNS topics](https://proxus.io/docs/develop/mqtt): receive values live instead of querying them. - [Historical import](https://proxus.io/docs/develop/historical-import): add older values to the same table. - [Reports](https://proxus.io/docs/analyze/reports): ready-made reports on the same data. --- # MQTT and the UNS topics > Subscribe to live tag values on the MQTT broker built into every edge gateway, with the Unified Namespace topic layout, the JSON payloads and Sparkplug B. Source: https://proxus.io/docs/develop/mqtt At the end of this guide, an MQTT client of yours receives every tag value of a gateway's devices as it is read, on topics that follow the plant's Unified Namespace. ## Before you start You need: - The address of the edge gateway whose devices you want. Each gateway runs its own broker and publishes only its own devices. The hub's gateway, **SYSTEM**, publishes the devices assigned to it. - The gateway's **MasterToken**, from the `[MQTTBroker]` section of that gateway's configuration file. If it is empty when the gateway starts, the gateway creates one and writes it into the file. - Network access to the broker port: `8883` for TLS, or `1883` without TLS (`MQTTBrokerPort`). - For TLS: the platform CA, from **Security > Certificate Store** with **Download CA**. - Any MQTT 3.1.1 or 5 client: MQTT Explorer, `mosquitto_sub`, or a library such as Python `paho-mqtt`. > **Note:** The device's place in the plant (enterprise, site, area, line or cell, equipment) decides its topic. Set it on the device, as described in [Unified Namespace](https://proxus.io/docs/concepts/unified-namespace). ## Step 1: Connect | Setting | Value | | --- | --- | | Host | the gateway's address | | Port | `8883` with TLS, or `1883` (or `MQTTBrokerPort`) without TLS | | User name | the gateway's `MasterToken` | | Password | empty | | TLS | on port 8883: verify the broker against the platform CA. See [Connect with TLS](#connect-with-tls). | The broker accepts a connection when the user name is the `MasterToken`, when it is the **Token** of a device on that gateway (shown on the device page), or when `AllowAnonymous = true`. Any other connection is refused with `Not authorized`. > **Warning:** `AllowAnonymous = true` lets anyone on the network read every value of the gateway. Leave it `false` and give the `MasterToken` only to systems that need it. The broker has no per-topic rights: a connected client can subscribe to every topic. ### Connect with TLS The broker accepts TLS on port **8883** with the gateway's own certificate, which the hub issues from the [Certificate Store](https://proxus.io/docs/administer/certificates). The port opens once the hub has issued the certificate. 1. In **Security > Certificate Store**, select **Download CA**. The file holds the CA certificates (PEM), no private key. 2. In your client, set port `8883` and use that file as the trusted CA. Connect to a host name or address that the gateway's certificate covers, because the name must match. ```bash mosquitto_sub -h -p 8883 --cafile proxus-ca.pem -u "" -t 'v1/#' -v ``` In the Python example below, call `client.tls_set(ca_certs="proxus-ca.pem")` and use port `8883`. Port **1883** stays open for devices without TLS. To accept TLS only, set `[MQTTBroker] PlainEnabled = false`. When the gateway's certificate is renewed, the broker restarts for a few seconds and clients connect again. ## Step 2: Subscribe Subscribe to `v1/#` for everything, or to a part of the tree. For example: | Subscription | Receives | | --- | --- | | `v1/#` | every topic of the gateway | | `v1/Meridian/Lyon_Foods_Plant/#` | everything of one site | | `v1/+/+/+/+/+/LYS_PACKER_04/telemetry/+` | each tag of one device, when its place has all five levels | ```python import os import paho.mqtt.client as mqtt BROKER = "localhost" PORT = 1883 TOKEN = os.environ["PROXUS_MQTT_TOKEN"] # the gateway's MasterToken def on_connect(client, userdata, flags, reason_code, properties): print("connected:", reason_code) client.subscribe("v1/#") def on_message(client, userdata, msg): print(msg.topic, msg.retain, msg.payload.decode()) client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="uns-reader") client.username_pw_set(TOKEN) client.on_connect = on_connect client.on_message = on_message client.connect(BROKER, PORT) client.loop_forever() ``` Run it with `PROXUS_MQTT_TOKEN= python3 uns_reader.py`. ## The topic layout ```text v1//////// ``` - `v1` is the namespace version. - The place levels come from the device. A level that is empty is left out, so the topic is shorter. A device with only a site and an area publishes under `v1/Lyon_Foods_Plant/Packaging/LYS_PACKER_04/...`; a device with no place at all publishes under `v1//...`. - Every character that is not a letter, a digit, `_` or `-` becomes `_`. `Lyon Foods Plant` becomes `Lyon_Foods_Plant`, `Line 1` becomes `Line_1`. - `` is `telemetry` for values and `state` for the device's state. | Topic | Retained | Sent | | --- | --- | --- | | `.../telemetry/` | no | every time the tag is read | | `.../telemetry/_summary` | no | all tags of the device in one message, at most every `SummaryIntervalMs` (5 s) | | `.../state/_lastSeen` | yes | the time of the latest reading, at most every `LastSeenIntervalMs` (5 s) | | `.../state/_status` | yes | `Online` when values arrive, `Offline` when the device is disabled or deleted. For a device that publishes its own values (see below), also `Offline` when its client disconnects and `Timeout` after five minutes without values. | Retained messages are kept by the broker and sent to a new subscriber at once, so a client that connects later still learns the status of every device. Set `UNSRetainMessages = false` to turn retaining off. ## The payloads One tag value, on `v1/Lyon_Foods_Plant/Packaging/LYS_PACKER_04/telemetry/Temperature`: ```json {"ts":"2026-10-15T19:01:43.450Z","value":25.4,"dataType":"Double","unit":"°C","quality":"Good","source":"Proxus"} ``` | Field | Meaning | | --- | --- | | `ts` | When the value was read, UTC, ISO 8601 with milliseconds. | | `value` | The value as a JSON number, `true`/`false` or string. | | `dataType` | `Bool`, `Int`, `Long`, `Float`, `Double`, `DateTime` or `String`. It is worked out from the value itself, so a `UShort` tag arrives as `Int`. | | `unit` | The tag's unit. Left out when the tag has none. | | `quality` | Always `Good` on this topic. Values that could not be read are not published here; see the device page for read errors. | | `source` | Always `Proxus`. | With `TelemetryThinPayload = false`, each tag message also carries a `context` object with `enterprise`, `site`, `area`, `processCell`, `equipmentModule`, `deviceId`, `deviceName` and `metric`. The summary, on `.../telemetry/_summary`: ```json { "ts": "2026-10-15T19:01:46.955Z", "deviceId": "48", "deviceName": "MFB_LYS_MIXER_3", "metrics": { "Speed": {"value": 386, "dataType": "Int", "unit": "rpm", "quality": "Good"}, "Running": {"value": true, "dataType": "Bool", "quality": "Good"} }, "context": {"enterprise": "Meridian", "site": "Lyon Foods Plant", "area": "Processing", "processCell": "Dough", "equipmentModule": "_none"}, "source": "Proxus" } ``` `context` is left out when `SummaryIncludeContext = false`. `_none` means the device has no equipment level. The state topics: ```json {"ts":"2026-10-15T19:01:39.551Z"} {"status":"Online","ts":"2026-10-15T18:14:07.999Z"} {"status":"Timeout","ts":"2026-10-15T19:20:00.000Z","reason":"Device timeout"} ``` ## Publish values from a device A device or program can send its own values to the broker. It connects with the device's **Token** as user name and publishes JSON to the topic `telemetry` (or any topic under `telemetry/`). Each field becomes a tag of that device: ```json {"Temperature": 21.7, "DoorOpen": false, "Pressure": {"value": 2.4, "unit": "bar"}} ``` Nested objects become dotted names (`Line.Speed`), and arrays get an index (`Axis[0]`). The values then go through the same path as values the gateway reads itself: storage, pipelines, outbound targets and the UNS topics. Writing to a device through MQTT, by publishing to a `command` topic, is not supported with the JSON format. Use a [rule action](https://proxus.io/docs/automate/rule-actions) or a [pipeline](https://proxus.io/docs/automate/pipelines) to write values. ## Sparkplug B Set `UNSPayloadFormat = "SparkplugB"` in the `[UNS]` section of the gateway's configuration and restart the gateway. The gateway then publishes Sparkplug B 3.0 messages on its own broker instead of the JSON topics above: - Topic namespace `spBv1.0//...`, with the gateway as edge node ``. - Each device is a Sparkplug device: a `DBIRTH` with its name, status, last-seen time and place, then `DDATA` with its tag values. Each metric carries `Source`, `Quality` and `Unit` properties. - The node answers the node commands `Node Control/Rebirth` (sends the births again), `discovery` and `refresh_metadata`. Sparkplug host applications connect with the `MasterToken` as user name, the same as JSON clients. ## Broker and UNS settings These keys are in the gateway's configuration file. See [Configuration keys](https://proxus.io/docs/reference/configuration) for the environment-variable form. | Key | Default | Meaning | | --- | --- | --- | | `[MQTTBroker] Enabled` | `true` | Runs the broker on this gateway. With `false` there is no broker and no UNS publishing. | | `[MQTTBroker] MQTTBrokerPort` | `1883` | The broker port. If it is taken, the gateway picks a free port and logs a warning, unless `AllowPortFallback = false`. | | `[MQTTBroker] TlsPort` | `8883` | The TLS port, with the gateway's certificate. `0` turns TLS off. | | `[MQTTBroker] PlainEnabled` | `true` | Accept connections without TLS on `MQTTBrokerPort`. `false` accepts TLS only. | | `[MQTTBroker] AllowAnonymous` | `false` | Accept clients without a user name. | | `[MQTTBroker] MasterToken` | created at first start | The user name for UNS and Sparkplug clients. | | `[MQTTBroker] EnableMQTTHooks` | `true` | Publishes the values the gateway reads to the UNS topics. With `false`, only values that devices publish themselves appear. | | `[UNS] UNSPayloadFormat` | `"JSON"` | `JSON` or `SparkplugB`. | | `[UNS] UNSRetainMessages` | `true` | Retain the state topics. | | `[UNS] UNSGroupId`, `UNSEdgeNodeId` | `"ProxusGroup"`, `"ProxusEdge"` | Sparkplug group and edge node. | | `[UNS.Optimizations] TelemetryThinPayload` | `true` | Leave `context` out of each tag message. | | `[UNS.Optimizations] SummaryIntervalMs` | `5000` | Least time between two summaries of a device. `0` sends one with every reading. | | `[UNS.Optimizations] SummaryIncludeContext` | `true` | Put `context` in the summary. | | `[UNS.Optimizations] SummaryOnlyOnChange` | `false` | Send a summary only when a value changed. | | `[UNS.Optimizations] LastSeenIntervalMs` | `5000` | Least time between two `_lastSeen` messages. | | `[UNS.Optimizations] StatusOnChangeOnly` | `true` | Send `_status` only when it changes. | The QoS levels are `0` for telemetry and `1` for state messages. ## What's next - [Unified Namespace](https://proxus.io/docs/concepts/unified-namespace): how the plant hierarchy is built. - [UNS Explorer](https://proxus.io/docs/organize/uns-explorer): browse the same tree in the hub. - [Outbound targets](https://proxus.io/docs/connect/outbound-targets): send values to your own MQTT broker instead. --- # Functions SDK > The C# base class and helpers for functions that run on edge gateways, with a complete example that adds a calculated tag and sends a notification. Source: https://proxus.io/docs/develop/functions-sdk A function is a C# class that Proxus compiles and runs on the edge gateways you choose. It sees the values the gateway reads, can change or add to them, and can save values, call other systems and send notifications. This page describes the programming interface. How to create, build and deploy a function in the hub is in [Functions](https://proxus.io/docs/automate/functions). ## The shape of a function A function is one class that derives from `FunctionBase` and passes the three constructor arguments on unchanged. The gateway creates it once when the function is deployed and stops it when it is removed or redeployed. ```csharp using System; using Proxus.Common; using Proxus.Common.Messages; using Proxus.SDK.BaseFunctions; namespace Proxus.Functions { // Adds a calculated tag to every reading of the case packers and warns when the motor current is high. public sealed class PackerPowerFunction(object sys, object log, object config) : FunctionBase(sys, log, config) { private const double CurrentLimit = 45.0; // A private const string ChannelName = "Shift supervisors"; private DateTime _lastWarning = DateTime.MinValue; protected override void OnStarted() { // Receive the readings of every device on this gateway. Use device IDs instead of "*" to narrow it. Subscriptions?.Add(new SubscriptionContext { Type = typeof(TransportData), Topics = ["*"] }); // Write a heartbeat to the function log every minute. ExecuteScheduledTask(TimeSpan.FromMinutes(1), () => LogInformation("PackerPowerFunction is running")); base.OnStarted(); } protected override void OnMessageReceive(FunctionContext ctx) { if (ctx.Message is not TransportData data) return; var deviceName = data.GetMetaDataValueByKey("DeviceName") ?? ctx.Topic; if (!deviceName.StartsWith("LYS_PACKER_", StringComparison.Ordinal)) return; var current = data.GetPayloadValueByName("MotorCurrent"); if (current <= 0) return; // A new tag on the same reading: it is stored and published like a tag read from the machine. var powerKw = Math.Round(400 * current * Math.Sqrt(3) * 0.85 / 1000, 2); data.SetPayloadValue("MotorPower", powerKw, "kW"); if (current > CurrentLimit && DateTime.UtcNow - _lastWarning > TimeSpan.FromMinutes(10)) { _lastWarning = DateTime.UtcNow; LogWarning($"{deviceName}: motor current {current} A is above {CurrentLimit} A"); SendNotification(ChannelName, $"{deviceName}: motor current {current} A is above {CurrentLimit} A"); } } } } ``` Rules that follow from how the gateway runs functions: - Add your subscriptions in `OnStarted`, then call `base.OnStarted()`. The base method connects the subscriptions, so a subscription added after it receives nothing. - `OnMessageReceive` is called for each reading, before the reading is stored, sent to outbound targets or run through pipelines. A payload you add or change on the `TransportData` object goes on with the reading. - Readings that a function itself produced (`BackToPipeline`, `Save`) are not delivered to functions again, so a function cannot loop on its own output. - Keep `OnMessageReceive` short. Start long work (HTTP calls, database queries) as a task and do not wait for it. ## Lifecycle | Member | When it runs | What to do there | | --- | --- | --- | | `protected virtual void OnStarted()` | Once, after deployment. | Add subscriptions, start timers, then call `base.OnStarted()`. | | `protected virtual void OnMessageReceive(FunctionContext ctx)` | For each message that matches a subscription. | Your logic. | | `protected virtual void OnStopping()` | When the function is undeployed or replaced. | Stop timers, dispose clients, then call `base.OnStopping()`. | | `public string? GatewayId`, `GatewayName` | Always. | The gateway the function runs on. | `FunctionContext` has `Topic` (for device data, the device ID) and `Message` (the object received, usually a `TransportData`). ## Subscriptions ```csharp Subscriptions?.Add(new SubscriptionContext { Type = typeof(TransportData), Topics = ["69", "70"], // device IDs, or "*" for every device on the gateway EdgeGateways = ["2"] // optional: also receive what gateway 2 publishes with PublishToEdgeGateways }); ``` | Field | Meaning | | --- | --- | | `Type` | `typeof(TransportData)` for device readings. `typeof(GenericMessage)` for messages published with `PublishLocal` or `Publish`. | | `Topics` | For readings: device IDs (the device's `Oid`), or `"*"`. For generic messages: the message topics. | | `EdgeGateways` | IDs of other gateways whose `PublishToEdgeGateways` output this function receives. | ## Reading and changing a reading A reading is a `TransportData`: a list of `Payload` (one per tag) and a list of `MetaData` (facts about the reading, such as `DeviceId`, `DeviceName`, `Enterprise`, `Site`, `Area`, `ProcessCell`, `EquipmentModule`). | Method (namespace `Proxus.Common`) | What it does | | --- | --- | | `T? GetPayloadValueByName(string payloadName)` | The tag's value converted to `T`, or `default` when the tag is absent. | | `object? GetPayloadValueByName(string payloadName)` | The tag's value. | | `string? GetMetaDataValueByKey(string key)` | A metadata value, for example `"DeviceName"`. | | `void SetPayloadValue(string payloadName, T? value, string unit = "")` | Sets a tag, or adds it when it is not there. | | `void AddPayload(string key, object? value, string? type, string unit = "")` | Adds a tag. `type` is a data type name such as `"Double"`. | | `void AddMetaData(string key, string value)` | Adds a metadata entry. | `Payload` has `Key`, `Value` (text), `NumericValue`, `Type`, `Unit` and `Time`. ## Sending data on | Method | What it does | | --- | --- | | `Task Save(TransportData data, bool usePipeline = true)` | Stores a reading of an existing device. The reading must have a numeric `DeviceId` metadata entry, or it is skipped with the warning `Save skipped: missing or invalid DeviceId in MetaData.` | | `Task Save(List payloads, string deviceName, bool usePipeline = true)` | Stores values under a device name. If no device of that name exists, Proxus creates one on this gateway. | | `void BackToPipeline(TransportData data)` | Sends a reading back into the gateway's normal path (storage, targets, pipelines). It needs a `DeviceId` metadata entry, or it logs `Error in BackToPipeline! DeviceId is null! Check your code.` | | `void PublishLocal(object message)` | Publishes a message to other functions on the same gateway. | | `Task PublishToEdgeGateways(TransportData data)` | Publishes a reading to functions on other gateways that list this gateway in `EdgeGateways`. | | `void PublishMqttMessage(string topic, string payload)` | Publishes to an MQTT broker. | | `void SubscribeToMqttTopic(string topic)` | Subscribes to an MQTT topic; override `HandleMqttMessage(MqttApplicationMessage message)` to receive. | The MQTT helpers connect to the broker given by the overridable properties `MqttBrokerHost` (default `"localhost"`), `MqttBrokerPort` (`1883`), `MqttBrokerUser` and `MqttBrokerPassword` (empty). Override them to reach another broker, or set `MqttBrokerUser` to the gateway's `MasterToken` to use the built-in one. ## Devices, notifications and databases | Method | What it does | | --- | --- | | `void SendNotification(string channelName, string message)` | Sends a message through the [notification channel](https://proxus.io/docs/connect/notification-channels) with this name. | | `Task UpdateDeviceStatusAsync(int deviceId, string status)` | Sets the status text shown for a device. | | `Task SwitchDeviceEnabledAsync(int deviceId, bool isEnabled)` | Turns a device on or off. | | `SelectStatementResult[]? ExecuteQuery(TargetType dbType, Dictionary parameters, string query)` | Runs a query on a database, given its type and the same parameters an [outbound target](https://proxus.io/docs/reference/outbound-targets) of that type uses. `TargetType.SystemDB` with `null` parameters reads the Proxus database. | | `int? ExecuteNonQuery(TargetType dbType, Dictionary parameters, string nonQuery)` | Runs a statement and returns the affected row count. | | `TransportData ExecuteQueryAndTransformResult(TargetType dbType, Dictionary parameters, string query)` | Runs a query and returns the rows as payloads. | ## Timers | Method | What it does | | --- | --- | | `CancellationTokenSource? ExecuteScheduledTask(TimeSpan period, Action action)` | Runs `action` every `period`. Cancel the returned source to stop. | | `CancellationTokenSource? ExecuteScheduledTask(TimeSpan period, Action action, bool align, bool strict = false)` | With `align: true`, runs on whole multiples of `period` (every full minute, every full hour). | | `CancellationTokenSource? SendRepeatedly(TimeSpan period, object message)` | Sends `message` to the function itself every `period`. | | `TimeSpan? EnableCacheWithExpirationTime` | Set before `base.OnStarted()` to keep received readings in `Cache` for this long. | Timers started with these methods are stopped for you when the function stops. ## Logging and failures `LogTrace`, `LogDebug`, `LogInformation`, `LogWarning`, `LogError` and `LogCritical` each take `(object message, bool asJson = false)`. The lines appear under **Logs** on the function and in [System logs](https://proxus.io/docs/administer/system-logs), prefixed with the class name. Two settings in the `[UserFunctions]` section of the gateway's configuration limit a misbehaving function: | Key | Default | Meaning | | --- | --- | --- | | `ExceptionThresholdPerFunction` | `10` | After this many unhandled exceptions, the gateway undeploys the function and marks it as not deployed. `0` means no limit. | | `LogLevelPolicy` | `["Error:2 1m", "Critical:2 1m"]` | The most log lines per level and time window, for example `"Warning:100 1h"`. When the limit is reached, one warning says so and further lines of that level are dropped until the window ends. | | `UseAutoTryCatchInjector` | `true` | The compiler wraps your methods so an exception is logged and counted instead of stopping the gateway. | There is no time or memory limit per call. A function that blocks or loops holds up the gateway's processing of the devices it subscribes to, so keep the work in `OnMessageReceive` small. ## What the compiler offers Your code can use the .NET base library (collections, LINQ, tasks, `HttpClient`, sockets, JSON, XML), the Proxus types above, MQTT client types and ML.NET. There is no package manager: a library outside this set cannot be referenced. For safety, code that uses these namespaces is refused when it is built, with the message `Blacklisted namespace used: . Reason: ...`: | Namespace | Reason given | | --- | --- | | `System.IO` | No direct file access. | | `System.Diagnostics` | No access to processes and system diagnostics. | | `System.Reflection` | No reflection. | | `System.Data`, `System.Data.Sql` | No direct database access. Use `ExecuteQuery` and `ExecuteNonQuery`. | | `System.Text.RegularExpressions` | No regular expressions. | | `System.Web`, `System.Drawing`, `System.Management`, `Microsoft.Win32`, `Microsoft.AspNetCore`, `Microsoft.VisualStudio` | Not available to functions. | Build errors are listed as ` (line , column ): `. ## Templates **Templates** on the function screen starts a function from one of these: | Template | What it does | | --- | --- | | Derived metrics | Adds calculated values (power from voltage and current, counter delta and rate) to incoming readings. | | Device health monitor | Marks devices healthy or stale from the time of their last reading. | | Historical JSON import | Imports timestamped JSON values into the historian. | | HTTP JSON polling | Polls a REST endpoint on a timer and saves chosen JSON fields as tags. | | MQTT JSON ingestion | Subscribes to an MQTT topic and saves the JSON properties as tags of the named device. | | OEE tracker | Calculates availability, performance, quality and OEE from production counters. | | Payload normalizer | Renames tags, converts units and scales values before they are stored. | | SQL polling ingestion | Reads a database table or view on a timer and saves the result as tags. | | Threshold alarm | Raises alarms with a cooldown and hysteresis and sends a notification. | ## What's next - [Functions](https://proxus.io/docs/automate/functions): create, build, deploy and read the logs of a function in the hub. - [Pipelines and rules](https://proxus.io/docs/concepts/pipelines-and-rules): when a function is the right tool and when a pipeline or rule is. - [Troubleshoot automation](https://proxus.io/docs/troubleshoot/automation): compile and deploy errors. --- # Historical import > Send older readings of a device to the Proxus historian in small batches over HTTP, with a key that makes every batch safe to retry. Source: https://proxus.io/docs/develop/historical-import At the end of this guide, your program sends readings that a device recorded in the past (from a data logger, a CSV export or a machine's own memory) to the Proxus historian. They are stored next to the device's live values and appear in trends, reports and the [Telemetry API](https://proxus.io/docs/develop/telemetry-api). ## Before you start You need: - The device in Proxus, enabled, on a running edge gateway. Note its **ID** (the `Oid` in the [REST API](https://proxus.io/docs/develop/rest-api)) and its **Token** (shown on the device page). - Network access to the gateway's HTTP port, `8083` by default (`Server-Port` in `[Service]`). - Historical import turned on. It is off in the delivered configuration; see the next section. ## Turn historical import on Set these keys, then restart the hub and the gateways: | Where | Key | Value | | --- | --- | --- | | Hub and every gateway that receives imports | `HistoricalImport__Enabled` | `true` | | The gateway that writes the Proxus historian (the hub's **SYSTEM** gateway in a standard installation) | `HistoricalImport__StorageEnabled` | `true` | While import is off, the endpoints answer `503`. ## Step 1: Send a batch ```text POST http://:8083/api/v1/devices//historical/batches X-IoT-Token: Idempotency-Key: lys-packer-04-2026-10-01-0001 Content-Type: application/json ``` ```json { "records": [ { "key": "Temperature", "time": "2026-10-01T06:00:00.000Z", "type": "Float", "value": 24.6, "unit": "°C" }, { "key": "Speed", "time": "2026-10-01T06:00:00.000Z", "type": "UShort", "value": 82, "unit": "rpm" }, { "key": "Running", "time": "2026-10-01T06:00:00.000Z", "type": "Bool", "value": true } ] } ``` | Field | Rules | | --- | --- | | `records` | 1 to 50 records. | | `key` | The tag name, up to 256 characters. | | `time` | ISO 8601 with `Z` or an offset such as `+02:00`, whole milliseconds at most, not in the future, not before 1900. | | `type` | Exactly one of `Bool`, `Short`, `UShort`, `Int`, `UInt`, `Float`, `Long`, `ULong`, `Double`, `String`, `Bytes`, `DateTime` (case matters). | | `value` | A JSON value that fits `type`: `true`/`false` for `Bool`, a number for the numeric types, a string for `String` (up to 4096 characters), Base64 text for `Bytes`, an ISO 8601 string for `DateTime`. `Long` and `ULong` must be within ±9007199254740991. | | `unit` | Optional, up to 64 characters. | Other fields in the body are refused. The whole body may be at most 256 KiB. The **Idempotency-Key** names the batch: 8 to 128 letters, digits, `-`, `_` or `.`. Sending the same key with the same body again is safe and returns the first answer. Sending the same key with a different body is refused. Use one key per batch, for example the source file name and a batch number. ## Step 2: Read the answer A new batch is answered with `202 Accepted`, a repeated one with `200`. The `Location` header points at the batch. ```json { "jobId": "5b0e6a5c-6f4e-4a0e-9a59-3f8f0f8c2d11", "state": "Pending", "results": [ { "index": 0, "state": "Pending" }, { "index": 1, "state": "Pending" }, { "index": 2, "state": "Rejected", "error": "InvalidTypeOrValue" } ], "storageDataset": "DeviceRawData" } ``` Each record has its own result, in the order you sent them. Rejected records are not stored; the others are. | Record error | Cause | | --- | --- | | `InvalidRecord` | Missing or too long `key`, too long `unit`, or no `value`. | | `InvalidTimestamp` | `time` missing, in the wrong format, in the future, before 1900 or finer than a millisecond. | | `InvalidTypeOrValue` | Unknown `type`, or a `value` that does not fit it. | | `MeasurementConflict` | The batch has the same tag and time twice with different values. The same tag, time and value twice is marked `Duplicate` instead. | ## Step 3: Follow the batch ```text GET http://:8083/api/v1/devices//historical/batches/ X-IoT-Token: ``` | Batch `state` | Meaning | | --- | --- | | `Pending` | Accepted, being written. | | `Completed` | Every accepted record is stored. | | `CompletedWithErrors` | Done, and at least one record was rejected. | | `NeedsReconciliation` | The storage did not confirm some records. Their result is `Uncertain`. Send the same batch again later with the same key. | Record states after writing: `Stored`, `Duplicate` (the same value for that tag and time is already stored), `Rejected` or `Uncertain`. ## Answers without a batch | Status | Body or header | Meaning | | --- | --- | --- | | `400` | `{"error":"InvalidIdempotencyKey"}` | The `Idempotency-Key` header is missing or not in the allowed form. | | `400` | `{"error":"InvalidJson"}` or `{"error":"InvalidBatch"}` | The body is not JSON, has unknown fields, or has no records or more than 50. | | `401` | | Missing `X-IoT-Token`, or the token does not belong to this device ID, or the device is disabled. | | `404` | | No batch with this ID for this device. | | `409` | `{"error":"IdempotencyConflict"}` | This key was used before with a different body. | | `413` | | The body is larger than 256 KiB. | | `415` | | `Content-Type` is not JSON. | | `429` | `Retry-After: 5` | The gateway is busy (8 requests at a time), or too many batches are still being written (8 per device, 64 in total). Wait and send again with the same key. | | `503` | | Import is turned off, or the hub cannot be reached. Send again later with the same key. | ## Example in Python ```python import time import requests GATEWAY = "http://localhost:8083" DEVICE_ID = 69 DEVICE_TOKEN = "" def send_batch(key, records): while True: response = requests.post( f"{GATEWAY}/api/v1/devices/{DEVICE_ID}/historical/batches", json={"records": records}, headers={"X-IoT-Token": DEVICE_TOKEN, "Idempotency-Key": key}, timeout=30, ) if response.status_code in (429, 503): time.sleep(int(response.headers.get("Retry-After", "5"))) continue response.raise_for_status() return response.json() batch = [ {"key": "Temperature", "time": "2026-10-01T06:00:00.000Z", "type": "Float", "value": 24.6, "unit": "°C"}, {"key": "Temperature", "time": "2026-10-01T06:01:00.000Z", "type": "Float", "value": 24.9, "unit": "°C"}, ] job = send_batch("lys-packer-04-2026-10-01-0001", batch) print(job["state"], [r["state"] for r in job["results"]]) ``` > **Note:** Imported values are stored with the device's current name. They do not run through pipelines, rules or outbound targets, and they are not published on the UNS topics: they are history, not live data. ## What's next - [Telemetry API](https://proxus.io/docs/develop/telemetry-api): check what was imported. - [Trend Workspace](https://proxus.io/docs/monitor/trend-workspace): see the imported values next to live ones. - [Network ports and endpoints](https://proxus.io/docs/reference/ports). --- # MCP server > Connect an AI assistant to the hub with the Model Context Protocol. It signs in as a Proxus user and reads plant model, device status, logs and telemetry. Source: https://proxus.io/docs/develop/mcp At the end of this guide, an AI assistant that speaks the Model Context Protocol (MCP), such as Claude, Cursor or VS Code, is connected to your hub. It can answer questions about devices, pipelines, rules and alerts from the live system, with the rights of the Proxus user it signs in as. ## Before you start You need: - The hub's address. The MCP server is at `/mcp` on the hub's port, for example `http://localhost:8080/mcp`. - A Proxus user for the assistant. Its role limits what the assistant may read and change. See [Users and roles](https://proxus.io/docs/administer/users-and-roles). - An MCP client that supports the Streamable HTTP transport. - `[MCP] Enabled = true` in the hub's configuration (the default). ## Step 1: Add the server to your client ```bash claude mcp add --transport http proxus http://localhost:8080/mcp ``` ```json { "servers": { "proxus": { "type": "http", "url": "http://localhost:8080/mcp" } } } ``` Most clients take a JSON entry with the server's URL: ```json { "mcpServers": { "proxus": { "url": "http://localhost:8080/mcp" } } } ``` No header or key is configured in the client. Signing in happens inside the conversation, in the next step. ## Step 2: Sign in Before it signs in, the assistant can only list the tools and call `schema_overview`, which explains the server and the sign-in step. Ask it to sign in and give it the Proxus user name and password when it asks. It calls `auth_login` with them. The sign-in is tied to this MCP connection and lasts `SessionTtlMinutes` (25 minutes by default). After that, or after `auth_logout`, the assistant asks again. `auth_whoami` shows which user the connection is signed in as. > **Warning:** The password passes through the conversation with the assistant. Use a dedicated user with a password that is not used anywhere else, and give its role only the rights the assistant needs. ## What the assistant can do | Tool | What it does | Who may use it | | --- | --- | --- | | `schema_overview` | Explains the server, the sign-in state and which tool fits which task. | anyone | | `auth_login`, `auth_whoami`, `auth_logout` | Sign in, show the signed-in user, sign out. | anyone | | `schema_entities` | Lists the object types (devices, profiles, rules, pipelines and others) and their readable fields. | signed in | | `schema_templates` | Example bodies for creating objects. | signed in | | `schema_protocols` | The connection settings and tag address formats of a protocol. | signed in | | `schema_telemetry` | Describes the stored values table and how to query it. | signed in | | `schema_odata_metadata` | A summary of the full data model. | administrators | | `odata_request` | Reads objects (GET only, at most 100 per call). | signed in | | `odata_mutate` | Creates or changes an object when you asked for that exact change. | signed in, with the role's rights | | `device_status` | Live online or offline state of the devices the user may see. | signed in | | `log_query` | Recent system log entries, filtered by level, source or text. | signed in | | `telemetry_query` | One read-only SQL query on the stored values, with row, time and memory limits. | administrators | | `graph_schema`, `graph_neighbors`, `graph_impact`, `graph_lineage`, `graph_paths`, `graph_context_pack` | What a device, rule, pipeline or dashboard depends on and what depends on it (the [operational graph](https://proxus.io/docs/organize/operational-graph)). | signed in | The server also offers three prompts, `proxus_read_entity`, `proxus_write_change` and `proxus_analyze_telemetry`, and resources under `proxus://schema/` (overview, entities, telemetry, templates, protocols). Every call runs with the signed-in user's permissions. A change the role does not allow is refused, as it would be in the hub's screens. Deleting is blocked by default even for users who may delete (`BlockDelete = true`). ## Secure it for production Set these in the `[MCP]` section of the hub's configuration (environment form `MCP__`): | Key | Default | Meaning | | --- | --- | --- | | `Enabled` | `true` | Turns the MCP server on or off. | | `ServerBaseUrl` | `""` | The hub's public address, for example `https://proxus.example.com`. Required when clients connect from other machines; empty works only through `localhost`. | | `AllowedBaseUrls` | `[]` | Other exact Proxus addresses `auth_login` may send credentials to. | | `AllowedOrigins` | `[]` | Browser origins allowed to call `/mcp`. Clients that are not browsers send none. | | `IPWhitelist` | `[]` | Addresses or ranges allowed to connect, for example `["10.0.0.0/8"]`. Empty allows all. | | `AdminOnly` | `false` | Only users with an administrative role may use the protected tools. | | `AllowedMethods` | `"GET,POST,PATCH,PUT"` | Methods `odata_mutate` may use. `"GET"` makes the assistant read-only. | | `BlockDelete` | `true` | Refuse deletes even if the role allows them. | | `BlockBulkOperations` | `false` | Refuse changes to several objects in one call. | | `RateLimitEnabled` | `true` | Limit calls per user and minute. | | `RateLimitRequestsPerMinute` | `60` | All calls. | | `ODataRateLimitRequestsPerMinute` | `30` | `odata_request` and `odata_mutate`. | | `TelemetryRateLimitRequestsPerMinute` | `120` | `telemetry_query`. | | `GraphRateLimitRequestsPerMinute` | `60` | The graph tools. | | `MaxConcurrentSessionsPerUser` | `0` | Open MCP sessions per user, `0` for no limit. | | `SessionTtlMinutes` | `25` | How long a sign-in lasts. | | `AuditLogging` | `true` | Logs every call with user, address, tool and result. | | `AnonymousDiscoveryMode` | `"ToolsAndOverview"` | What clients see before signing in: `ToolsAndOverview`, `ToolsOnly` or `Disabled`. | | `DebugLogging` | `false` | Detailed request logging for connection problems. | `[MCP.ClickHouse]` limits `telemetry_query`: `MaxResultRows` (1000), `MaxRowsToRead` (10000000), `MaxBytesToRead` and `MaxMemoryUsage` (512 MiB), `MaxExecutionTimeSeconds` (10), `MaxThreads` (4) and `MaxResultBytes` (16 MiB). Set `Username` and `Password` to a database user that may only read the `DeviceRawData` and `Logs` tables. When several hub instances run behind a load balancer, sign-ins are shared through Redis when `Cluster:RedisConnection` (or `MCP:RedisConnection`) is set. Refusals reach the client as errors: `403` when the address is not allowed, an `authorization_denied` error when an administrative tool is called by a user without an administrative role, `401` when a protected tool is called before signing in, `429` when a rate limit is reached. ## What's next - [REST API](https://proxus.io/docs/develop/rest-api): the same data for your own programs. - [Operational graph](https://proxus.io/docs/organize/operational-graph): what the graph tools read. - [Security hardening](https://proxus.io/docs/operate/security). --- # Reference > Facts to look up. Protocols, outbound targets, notification channels, pipeline nodes, configuration keys, network ports and the words the hub uses. Source: https://proxus.io/docs/reference These pages list what the product offers, taken from the product itself. They do not explain how to do a task; for that, follow the links on each page to the how-to guides. --- # Protocols > The protocols the edge gateway runs, by vendor, with the default port and which ones support a connection test, browsing and discovery. Source: https://proxus.io/docs/reference/protocols This list is the set of protocols the edge gateway runs, the same set the device setup wizard offers. Protocol names appear here as they do in the hub. ## What the columns mean - **Port when empty**: the port the gateway uses when you leave **Port** empty. "Enter it" means the protocol has no usual port and the device's port must be typed in. - **Test**: the wizard's **Test the connection** works for every protocol on this page. The gateway connects to the address, opens a protocol session and, if you added tags, reads them once. - **Browse**: the protocol can list the device's values for you (**From the device** in the wizard's tag step). - **Discovery**: the wizard can search the network for servers of this protocol (**Server discovery**). - **Over TCP** in a name means a serial protocol carried over TCP, through a serial device server or a converter. Proxus does not open serial (COM) ports directly. ## Open standards | Protocol | Port when empty | Browse | Discovery | Notes | | --- | --- | --- | --- | --- | | **OPC UA** | from the endpoint URL (`opc.tcp://server:4840`) | Yes, folder by folder | Yes | Discovery tries `opc.tcp` 4840 and 53530 and `opc.https` 53443 (`[Browse] OpcUaDiscoveryPorts`). Server certificates are trusted in the hub. See [OPC UA](https://proxus.io/docs/connect/devices/opc-ua). | | **Modbus TCP** | 502 | No | No | Datasheet numbers such as `40001` are converted for you. | | **Modbus RTU Over TCP** | 502 | No | No | | | **Modbus ASCII Over TCP** | 502 | No | No | | | **MTConnect** | enter it | Yes | Yes | An MTConnect agent over HTTP. Discovery tries ports 5000, 5001, 5005, 5006 and 7000 (`[Browse] MtConnectDiscoveryPorts`). See [MTConnect](https://proxus.io/docs/connect/devices/mtconnect). | | **SNMP** | 161 (UDP) | Yes | No | | | **Simulator** | none | No | No | Values generated on the gateway, for trying pipelines, dashboards and rules without a device. See [Simulator](https://proxus.io/docs/connect/devices/simulator). | ## Siemens | Protocol | Port when empty | Browse | Discovery | Notes | | --- | --- | --- | --- | --- | | **Siemens S7-1500** | 102 | No | No | The wizard shows one **Siemens S7** card with a switch for the CPU family. The test also reads the CPU's order number. | | **Siemens S7-1200** | 102 | No | No | | | **Siemens S7-300** | 102 | No | No | | | **Siemens S7-400** | 102 | No | No | | | **Siemens S7-200 Smart** | 102 | No | No | | | **Siemens S7-200** | 102 | No | No | | | **Siemens PPI Over TCP** | enter it | No | No | | ## Rockwell Automation | Protocol | Port when empty | Browse | Discovery | Notes | | --- | --- | --- | --- | --- | | **Allen Bradley** | 44818 | Yes | No | ControlLogix and CompactLogix (EtherNet/IP, CIP). Browsing lists the controller's tags. | | **Allen Bradley MicroCip** | 44818 | No | No | | | **Allen Bradley PCCC** | 44818 | No | No | | | **Allen Bradley SLC** | 44818 | No | No | | ## Mitsubishi Electric | Protocol | Port when empty | Browse | Discovery | | --- | --- | --- | --- | | **Mitsubishi Melsec MC** | enter it | No | No | | **Mitsubishi Melsec MC ASCII** | enter it | No | No | | **Mitsubishi Melsec MC R** | enter it | No | No | | **Mitsubishi Melsec A1E** | enter it | No | No | | **Mitsubishi Melsec A1E ASCII** | enter it | No | No | | **Mitsubishi Melsec A3C Over TCP** | enter it | No | No | | **Mitsubishi Melsec CIP** | 44818 | No | No | | **Mitsubishi Melsec FX Links Over TCP** | 485 | No | No | | **Mitsubishi Melsec FX Serial Over TCP** | enter it | No | No | ## Omron | Protocol | Port when empty | Browse | Discovery | | --- | --- | --- | --- | | **Omron FINS** | 9600 | No | No | | **Omron CIP** | 44818 | No | No | | **Omron Host Link Over TCP** | enter it | No | No | | **Omron Host Link C Mode Over TCP** | enter it | No | No | ## Other PLC vendors | Protocol | Port when empty | Browse | Discovery | | --- | --- | --- | --- | | **Beckhoff ADS** | enter it: left empty, the gateway uses 851, which is not the ADS TCP port (usually 48898) | No | No | | **Delta TCP** | 502 | No | No | | **Delta Serial Over TCP** | 502 | No | No | | **Delta Serial ASCII Over TCP** | 502 | No | No | | **FATEK Program Over TCP** | enter it | No | No | | **Fuji SPH** | 18245 | No | No | | **Fuji SPB Over TCP** | enter it | No | No | | **GE SRTP** | 18245 | No | No | | **Inovance TCP** | 502 | No | No | | **Inovance Serial Over TCP** | 502 | No | No | | **Keyence MC** | enter it | No | No | | **Keyence MC ASCII** | enter it | No | No | | **Keyence Nano Serial Over TCP** | 8501 | No | No | | **LSIS XGB Fast Ethernet** | 2004 | No | No | | **LSIS XGB Cnet Over TCP** | 2004 | No | No | | **LSIS XGK Fast Ethernet** | 2004 | No | No | | **MegMeet TCP** | 502 | No | No | | **MegMeet Serial Over TCP** | 502 | No | No | | **Panasonic MC** | enter it | No | No | | **Panasonic Mewtocol Over TCP** | enter it | No | No | | **Toyo PUC** | enter it | No | No | | **Vigor Serial Over TCP** | enter it | No | No | | **XINJE TCP** | 502 | No | No | | **XINJE Serial Over TCP** | 502 | No | No | | **XINJE Internal** | 502 | No | No | | **YASKAWA Memobus TCP** | 502 | No | No | | **Yokogawa Link TCP** | enter it | No | No | | **Freedom TCP** | enter it | No | No | Since 2.0.0, **Mitsubishi Melsec A1E ASCII** devices use the A1E ASCII protocol (before, they could not connect), and **XINJE TCP** and **XINJE Serial Over TCP** each use their own driver (before, the two were swapped). No setting change is needed. ## CNC machines | Protocol | Port when empty | Browse | Discovery | | --- | --- | --- | --- | | **Fanuc Series 0i** | 8193 | No | No | | **Haas MDC** | 5051 | No | No | | **Heidenhain LSV2** | 19000 | No | No | MTConnect, in the first table, is the usual way to read other CNC controls through an agent. ## Robots and other devices | Protocol | Port when empty | Browse | Discovery | | --- | --- | --- | --- | | **Fanuc Interface** | 60008 | No | No | | **Kuka TCP** | 7000 | No | No | | **YASKAWA YRC1000 TCP** | 10040 | No | No | | **Estun TCP** | 502 | No | No | | **ER7BC10** | 8080 | No | No | | **Turck Reader** | enter it | No | No | ## Protocols that are not available These protocols are not part of the gateway in this release, and are not offered when you add a device: IEC 104, DLT 645/698, CJT 188, Atlas Copco Open Protocol, SECS/HSMS, the UDP variants of Modbus, Omron FINS, Melsec MC and Memobus, and MQTT and HTTP as device protocols. If your equipment needs one of them, [ask us about it](/contact?topic=equipment). To bring in data from a device that speaks MQTT or HTTP, let it publish to the gateway's broker (see [MQTT and the UNS topics](https://proxus.io/docs/develop/mqtt#publish-values-from-a-device)) or poll it with a [function](https://proxus.io/docs/develop/functions-sdk). ## Related - [Add a device](https://proxus.io/docs/connect/devices/add-a-device) - [Device profiles](https://proxus.io/docs/connect/device-profiles) - [Troubleshoot devices](https://proxus.io/docs/troubleshoot/devices) --- # Outbound target types > Every kind of outbound target, the parameters each one reads, how values are sent, and what Check and Test Connection prove. Source: https://proxus.io/docs/reference/outbound-targets An outbound target sends a device's values to a system outside Proxus. This page lists every target type, the parameters each type reads and how the gateway sends to it. To create one, see [Outbound targets](https://proxus.io/docs/connect/outbound-targets). ## Fields of every target | Field | Meaning | | --- | --- | | **Profile Name** | A unique name. | | **Type** | The kind of target, from the tables below. Cannot be changed on **SYSTEM INTERNAL DB**. | | **Transport Strategy** | **Pass Through**: every reading with all its values. **On Change**: only the values that changed; a reading with no change sends nothing. **Pipelines Only**: nothing from normal device delivery; only pipelines that name this target send to it. | | **Parameters** | Key and value rows. The keys each type reads are listed below. Values of keys such as `Password`, `Token` or `Secret` are masked. | | **Status** | `Ready`, `Running`, `Degraded`, `Error` or `Stopped` as reported by the gateways, `Unused` when no device uses the target, `Unknown` when nothing has been reported yet. With **Last Success**, **Last Failure** and **Last Error**. | | **Devices Used** | How many devices send to this target. | The gateway that reads a device also sends its values to the device's targets, so the target must be reachable from that gateway's network. ## Check and Test Connection **Check** on a saved target opens a check of its parameters and shows the health reported by the gateways. - The parameter check lists **Errors** (the target cannot work, for example a required key is missing), **Warnings** and **Notes** (a key the type does not read, with a suggestion when it looks like a typo, or a key left empty that falls back to a placeholder value). - **Test Connection** then connects to the target from the hub or from a gateway you choose and reports one of: `Connected` (the target accepted the credentials), `Reachable` (something answers at the address, credentials not verified), `Failed` with the reason, or no probe available for the type. No data is written by the test. The **Probe** column below says what the test proves for each type. ## Message brokers and streaming | Type | Parameters (required in bold) | Probe | | --- | --- | --- | | **MQTT** | **`BrokerHost`**, `BrokerPort` (1883), `Username`, `Password`, `UseTls` (false), `TlsVersion` (Tls12), `CertificateThumbprint`, `ServerCertificateThumbprint`, `Topic` (falls back to `proxus_device_data`), `QualityOfServiceLevel` (1), `MaxBatchSize` (50), `MessageBatchTimeoutMs` (500), `ConnectionTimeoutSec` (5), `MaxReconnectAttempts` (10), `InitialReconnectDelayMs` (1000), `MaxReconnectDelayMs` (30000), `HealthCheckIntervalSec` (10) | Connects and checks the broker's answer. | | **SparkplugB** | `BrokerHost` (falls back to `localhost`), `BrokerPort` (1883), `Username`, `Password`, `GroupId` (`ProxusGroup`), `EdgeNodeId`, `ScadaHostIdentifier` (`scada1`), `UseTls` (false), `UseWebSocket` (false), `TlsVersion`, `CertificateThumbprint`, `ServerCertificateThumbprint`, `ReconnectInterval` (5 s) | Connects and checks the broker's answer. | | **Kafka Messaging System** | `BootstrapServers` (falls back to `localhost:9092`), `Topic` (falls back to `proxus_device_data`), `ClientId`, `SecurityProtocol`, `SaslMechanism`, `SaslUsername`, `SaslPassword` | Asks the cluster for its brokers and whether the topic exists. | | **RabbitMQ Messaging System** | `HostName`, `UserName`, `Password` (fall back to `localhost`, `guest`, `guest`), `Port` (5672), `VirtualHost` (`/`), `Exchange`, `RoutingKey` | Signs in to the virtual host and checks the exchange. | | **Redis Database** | `Host` (falls back to `localhost`), `Port` (6379), `Password`, `Database` (0), `DataType` (`hash`) | Signs in and sends `PING`. | `Username` and `Password` on MQTT are used only when both are set. ## Cloud services | Type | Parameters (required in bold) | Probe | | --- | --- | --- | | **AWS IoT Core** | **`EndPoint`**, **`CertificateThumbprint`** (the thing's device certificate in the [Certificate Store](https://proxus.io/docs/administer/certificates), chosen as **Client Certificate**), **`ClientId`**, `Port` (8883), `UseTls` (true), `ServerCertificateThumbprint` (Amazon Root CA 1), `Topic` (falls back to `proxus_device_data`), and the batch and reconnect keys of MQTT | Connects with the certificate. | | **Azure IoT** | **`HostName`** (for example `my-hub.azure-devices.net`), **`DeviceId`**, **`SharedAccessKey`**, `OperationTimeoutMs` (30000), `RetryMaxAttempts` (5), `RetryMinBackoffMs` (200), `RetryMaxBackoffMs` (5000), `RetryDeltaBackoffMs` (200) | Opens the device connection. | | **Azure Data Lake Gen2** | **`AccountName`**, **`FileSystem`**, **`TenantId`**, **`ClientId`**, **`ClientSecret`**, `Directory`, `PathPattern`, `Format` (`parquet`, `json` or `csv`), `CsvDelimiter`, `CreateIfNotExists`, `DefaultRegion`, `DefaultSubject`, `FlushIntervalSeconds` (30), `MinBatchCount` (5000), `MinBatchBytes` (16 MiB), `MaxBatchCount` (100000), `MaxBatchBytes` (64 MiB), `MaxWaitSeconds` (300) | Signs in and checks that the file system exists. | ## Time-series and analytics databases | Type | Parameters (required in bold) | Probe | | --- | --- | --- | | **ClickHouse** | `Host` (falls back to `localhost`), `Port` (8123, HTTP), `Database`, `Table`, `Username`, `Password`, `TTLExpression`, `LogTTLExpression`, `WriteIntervalSeconds` (1) | Runs `SELECT 1`. | | **InfluxDB** | `Url` (falls back to `http://localhost:8086`), `Token`, `Organization` (`proxus`), `Bucket` (`proxus`), `Measurement` (`proxusdevicedata`) | Checks the token and that the bucket exists. Each value is written as one point at the time it was read, tagged `deviceName` and `deviceId`; numbers and booleans keep their type. | | **TDengine** | `Host` (falls back to `localhost`), `Port` (6041), `Username` (`root`), `Password` (`taosdata`), `Database`, `StableName`, `Keep` (365), `Duration` (10), `Buffer` (256) | Signs in. | | **Splunk** | `Url` (the HTTP Event Collector), `Token`, `UseAcknowledgment` (false). HTTPS follows the `Url` (`https://`); the older `UseSSL` has no effect. Each event carries the time its value was read, so values sent after an outage are indexed at the right time | Checks the collector's health and the token. | ## REST API | Type | Parameters (required in bold) | Probe | | --- | --- | --- | | **REST API** | **`Uri`** (absolute `http` or `https` address), `AuthenticationType`, `Username`, `Password`, `Token`, `APIKey` | Sends a `HEAD` request. | Each reading is sent as a JSON `POST` to `Uri`. `AuthenticationType` decides the credentials: `Basic` (with `Username` and `Password`), `Token` (sent as `Authorization: Bearer `) or `APIKey` (sent as the header `X-Api-Key`). Any other value, including `Bearer` and `OAuth`, sends no credentials. A REST API target can also be called from a pipeline's **Call Api** node; set its strategy to **Pipelines Only** for that use. ## Relational databases The gateway creates the table it needs on first write. | Type | Parameters (all required) | Probe | | --- | --- | --- | | **Microsoft SQL Server** | `Server`, `User`, `Password`, `Database`; optional `TrustServerCertificate`, `Encrypt` | Opens a connection. | | **PostgreSQL Database** | `Server`, `User`, `Password`, `Database`; optional `Port` | Opens a connection. | | **MySQL Database** | `Server`, `User`, `Password`, `Database`; optional `Port` | Opens a connection. | | **Oracle Database** | `Server` (data source or TNS name), `User`, `Password` | Opens a connection. | | **Firebird Database** | `Server`, `User`, `Password`, `Database` | Opens a connection. | | **System Database** | none | none. This is the Proxus historian itself (**SYSTEM INTERNAL DB**). | ## Types that cannot be used in this version The type list also contains these, but they do not work in this release: | Type | Why | | --- | --- | | **IBM DB2**, **SAP HANA**, **SQLite Database**, **VistaDB**, **Advantage Database**, **Adaptive Server Enterprise**, **SQL Anywhere**, **Pervasive Database** | The gateway does not include a database driver for them, so writing fails. | | **Microsoft Access** | Needs a Windows-only driver that the gateway does not have. | | **XML File** | The file is opened read-only, so nothing can be written. | To write to one of these databases, send the values to a supported target or a [function](https://proxus.io/docs/develop/functions-sdk) that writes them. ## TLS parameters Every TLS connection verifies the server: its certificate must match the address and chain to a trusted root, which is the target's trusted server certificate from the [Certificate Store](https://proxus.io/docs/administer/certificates) or the operating system's roots. No target accepts an unknown certificate, and **Test Connection** verifies the same way. Thumbprints are copied from the Certificate Store. The gateway reads the certificates from the store at every send, so a renewed or replaced certificate is used without changing the target. | Type | TLS settings | | --- | --- | | **MQTT**, **AWS IoT Core**, **SparkplugB** | **Trusted Server Certificate** field in the parameter form: any CA or server certificate in the store, the Proxus Platform CA included. The client certificate is uploaded with **Certificates**. | | **Kafka Messaging System** | With `SecurityProtocol` `Ssl` or `SaslSsl`: `CertificateThumbprint` (client certificate), `ServerCertificateThumbprint` (trusted CA). The broker's host name is verified. | | **RabbitMQ Messaging System** | `UseTls`, `CertificateThumbprint`, `ServerCertificateThumbprint`. The default TLS port is 5671. | | **Redis Database** | `UseTls`, `CertificateThumbprint`, `ServerCertificateThumbprint`. | | **ClickHouse** | `UseTls`, `CertificateThumbprint`, `ServerCertificateThumbprint`. The default TLS port is 8443. | | **REST API**, **InfluxDB**, **Splunk** | An `https` address is verified. `CertificateThumbprint` and `ServerCertificateThumbprint` are optional. | | **TDengine** | `UseTls` (verified against the operating system's roots). | | **PostgreSQL Database** | `SslMode`: `Disable`, `Allow`, `Prefer`, `Require`, `VerifyCA` or `VerifyFull`, and `ServerCertificateThumbprint` for the verifying modes. | | **MySQL Database** | `SslMode`: `None`, `Preferred`, `Required`, `VerifyCA` or `VerifyFull`, and `ServerCertificateThumbprint` for the verifying modes. | When `SslMode` is not set, the database's own default applies. Uploading a certificate with **Certificates** (PEM certificate and key, optional CA file) adds the CA to the store and sets it as the target's trusted server certificate. For **AWS IoT Core** that is Amazon Root CA 1, downloaded by Proxus; without internet access the operating system's roots are used. Step-by-step setup for each type, AWS IoT Core included, is in [Secure connections to targets](https://proxus.io/docs/connect/secure-target-connections). ## Buffering Every working target type keeps data in a durable queue on the gateway. Data enters the queue first and leaves it only after the target took it, so values read while the target is down, restarting or unreachable (also when the gateway starts) are written in order when it is back. - Data waits for the gateway's **Buffer Retention (hours)**: default 48 hours, up to 30 days. - While the target is unreachable, its status error says how many queued messages are waiting at the gateway. - A record the target answers but never accepts (for example a value too long for the column) is skipped after a few attempts and named in the status. The data behind it does not wait. - Delivery is at least once: rarely, a record that was written but whose confirmation was lost is written twice. ## Related - [Outbound targets](https://proxus.io/docs/connect/outbound-targets): create a target and attach it to devices. - [Troubleshoot data](https://proxus.io/docs/troubleshoot/data): values missing in a target. --- # Notification channel types > Every kind of notification channel, the parameters each one needs, how messages are retried, and what the Test action shows. Source: https://proxus.io/docs/reference/notification-channels A notification channel is a way for Proxus to send a message to people: by email, SMS or a chat service. Rules, pipelines and functions send through a channel by naming it. This page lists every channel type and its parameters. To create one, see [Notification channels](https://proxus.io/docs/connect/notification-channels). ## Fields of every channel | Field | Meaning | | --- | --- | | **Name** | A unique name, for example `Ops Slack #alerts`. Functions refer to the channel by this name. | | **Notification Type** | The kind of channel, from the table below. | | **Description** | Free text. | | **Parameters** | Key and value rows. The keys each type reads are listed below. Secret values are masked. | | **Status** | `Configured`, `Missing: ` when required keys are empty, `Sample values` when the channel still has the example values it was created with, or `Delivery failing` when the last send failed after the last success. | | **Last Success** | When a notification last went out through the channel. | | **Last Failure** | When a send through the channel last failed. | | **Last Error** | The reason the provider gave for the last failure. Cleared by the next successful send. | | **Actions** | How many rule actions send through this channel. | ## Channel types Required keys are in bold. | Type | Parameters | Sent with | | --- | --- | --- | | **Email Notification** | **`SmtpServer`** (for example `smtp.office365.com`), `SmtpPort` (587), **`Username`**, **`Password`**, **`From`**, **`To`** (one or more addresses separated by `,` or `;`), `Cc`, `Bcc`, `UseSsl` (true) | Your SMTP server. The subject is the message title. | | **SMS Notification** | **`AccountSid`**, **`AuthToken`**, **`From`** (a Twilio number in E.164 form, `+31201234567`), **`To`** (E.164) | Twilio | | **WhatsApp Notification** | **`AccountSid`**, **`AuthToken`**, **`From`** (a Twilio WhatsApp sender in E.164 form), **`To`** (E.164) | Twilio. Enter the numbers without the `whatsapp:` prefix; Proxus adds it. | | **Push Notification** | **`Token`** (the device registration token), `FCM_V1` (true); with `FCM_V1 = true`: **`ProjectId`** and **`AccessToken`**; with `false`: **`ServerKey`** | Firebase Cloud Messaging | | **Slack Message** | **`WebhookUrl`** (a Slack incoming webhook), `BlocksJson` (optional Slack blocks) | Slack | | **Microsoft Teams Message** | **`WebhookUrl`** (a Teams incoming webhook) | Microsoft Teams, as a message card | | **Discord Message** | **`WebhookUrl`** (a Discord webhook) | Discord | | **Telegram Message** | **`BotToken`**, **`ChatId`**, `ParseMode` (`MarkdownV2` or `HTML`) | Telegram Bot API | | **Line Message** | **`AccessToken`** (channel access token), **`UserId`** | LINE | | **Facebook Messenger Message** | **`AccessToken`** (page access token), **`RecipientId`**, **`Message`** | Facebook Messenger | > **Warning:** **Pusher Notification** is in the type list but cannot send in this release. A channel of this type is refused with `Pusher channels cannot be sent by this platform version.` Use another type. > **Note:** A **Facebook Messenger Message** channel sends the text stored in its own `Message` parameter, not the text of the rule or pipeline that triggered it. The other types send the triggering message. ## What is sent - From a rule: the title `Proxus Notification` and the alert message as the body. - From a pipeline's **Notification** node: the title `Proxus Pipeline Notification` and the node's message. - From a function's `SendNotification`: the text the function passes. Chat channels show only the body. Email uses the title as its subject. ## Delivery and retries A message that cannot be delivered is tried again up to five times in total, after about 5 seconds, 30 seconds, 5 minutes and 1 hour. A channel with missing or invalid parameters is not retried: fix the channel and the next message goes through. Web services that answer with a server error are tried again at once, up to two more times, and a "too many requests" answer is respected for up to three attempts. Each send has a 15-second limit. ## Test a channel Select **Test** on a saved channel. It sends a real message. 1. The dialog shows the result of the parameter check (`All required parameters are present.` or `Missing or invalid parameters:` with the list), a **Title** and a **Body** filled in for you, and an optional recipient that replaces `To`, `ChatId`, `UserId`, `RecipientId` or `Token` for this test. Webhook channels (Slack, Teams, Discord) have no recipient to replace. 2. Select **Send Test**. 3. The result is `Sent successfully. The provider accepted the message.` with the time it took, or the reason it was not sent. | Result | Meaning | | --- | --- | | `Not sent: channel parameters are incomplete.` | A required key is missing or a value has the wrong form. The message lists which. | | `Not sent: test rate limit.` | A test of this channel ran less than 15 seconds ago. | | `Not sent: the attempt timed out.` | The provider did not answer in time. | | `Send failed.` | The provider refused the message. The reason shows its answer, for example `Slack failed: 404 Not Found`. | "Accepted" means the provider took the message. It does not prove that it reached the recipient's inbox or app. ## Related - [Notification channels](https://proxus.io/docs/connect/notification-channels): create a channel. - [Rule actions](https://proxus.io/docs/automate/rule-actions): send a notification when a rule fires. - [Pipeline nodes](https://proxus.io/docs/reference/pipeline-nodes#notification): the **Notification** node. --- # Pipeline nodes > Every node of the pipeline editor with what it does, its settings, its outputs and the pipeline kinds it can be used in, plus the limits of a pipeline. Source: https://proxus.io/docs/reference/pipeline-nodes This page lists every node of the pipeline editor's **Canvas** tab. Each node has two names: the one in the palette (used as the heading here) and the one at the top of its settings panel (given after "Panel name"). The **Build** tab creates the same nodes from plain steps. How to build and publish a pipeline is in [Pipelines](https://proxus.io/docs/automate/pipelines). ## Two kinds of pipeline | Execution class | Runs | Starts from | Can use | | --- | --- | --- | --- | | **Transport Pipeline** | on each reading, before it is stored or sent anywhere. It can change, drop or set aside data. | exactly one **Transport Input** | the nodes marked **T** below | | **Automation** | after the reading is stored. The stored data is not changed; the pipeline opens alarms, sends messages, writes to devices or calls APIs. | 1 to 8 source nodes | the nodes marked **A** below | ## Outputs and errors Most nodes have one output, **out**, and an **error** output. Routing nodes have their own outputs, listed with each node. When a node fails and nothing is connected to its **error** output: - in an automation pipeline, processing of that event stops and the error is counted; - in a transport pipeline, the pipeline's **On error** setting decides: **Pass Original** (default: the reading goes on unchanged), **Drop** or **Quarantine**. Nodes without outputs (marked "ends the branch") are the last step of a branch. ## Field names Settings that name a field use a path: `payload.` for a tag value, `metadata.`, `attributes.`, `topic`, `origin`, `device.*`, `gateway.*` or `hierarchy.*`. A tag name starts with a letter or `_` and has at most 80 characters. The device and gateway identity (`device.id`, `gateway.id`, `metadata.DeviceId`, `metadata.GatewayId`) cannot be changed or removed. Under **Which data** (on sources) and **Conditions** (on **Filter** and **Switch**) you choose which readings a node handles: by device, gateway, device profile, protocol, place (enterprise, site, area, line or cell, equipment), tag, topic, a tag's value, type, unit or quality. **Required tags (advanced)** on a source limits the pipeline to devices that have those tags. ## Sources ### Transport Input Panel name **Incoming data**. **T**. Starts the pipeline for each reading of a matching device, before it is stored or forwarded. Only one per pipeline. | Setting | Values | | --- | --- | | **Run on** | **Every value** (default) or **Only when the value changes**. | ### Telemetry Input Panel name **Device values**. **A**. Starts the pipeline when devices send new tag values. **Run on**: **Every value** or **Only when the value changes**. ### Device Status Input Panel name **Device status**. **A**. Starts the pipeline when a device connects, disconnects or changes state. No settings besides **Which data**. ### Gateway Status Input Panel name **Gateway status**. **A**. Starts the pipeline when a gateway connects or disconnects. ### Operational Log Input Panel name **System log**. **A**. Starts the pipeline from platform log entries (warnings, errors). ### Runtime Metrics Input Panel name **Runtime metrics**. **A**. Starts the pipeline from the gateway's performance figures. ### Schedule Input Panel name **Schedule**. **A**. Starts the pipeline at fixed times. | Setting | Values | | --- | --- | | **Schedule** | Five fields: minute, hour, day of month, month, day of week (0 to 7, both 0 and 7 are Sunday). `*`, lists (`1,15`), ranges (`8-17`) and steps (`*/5`) are allowed. Default `*/5 * * * *`. | | **Time zone** | Default UTC. | The schedule is checked once a minute. Runs missed while the gateway was off are not made up. ### No Data Input Panel name **No data**. **A**. Notices when a device stops sending values, and when it starts again. | Setting | Values | | --- | --- | | **Silence threshold (minutes)** | 1 to 10080. Default 5. | Outputs **missing** and **restored**, each sent once per change. It is checked once a minute, so it can fire up to a minute after the threshold. ## Shape data ### Filter **T A**. Lets through only the data that matches **Conditions**; the rest goes to **false**. With no condition everything passes. Outputs **true**, **false**. ### Select Fields Panel name **Keep fields**. **T A**. Keeps only the tags you list and removes the others. Setting **Fields to keep**. ### Set Field **T A**. Writes a value into a field. | Setting | Values | | --- | --- | | **Destination** | The field to write. | | **Value source** | **Copy from field** (then **Source field**) or **Constant** (then **Constant value**: text, number or true/false). | A missing source field is an error. ### Rename Field **T A**. Settings **From** and **To**. A missing field is an error. ### Remove Field **T A**. Setting **Field**. ### Convert Type **T A**. Settings **Field** and **Target type**: Number (default), Integer, Boolean, String, DateTime or Any. A value that cannot be converted goes to **error**. ## Calculate ### Calculate **T A**. Computes a new value from other fields. | Setting | Values | | --- | --- | | **Formula** | Numbers, tag names, `+ - * /`, brackets and the functions `abs(x)`, `round(x)`, `min(a, b)`, `max(a, b)`, `clamp(value, low, high)`. For example `flow * 60` or `round(power / 1000)`. At most 1024 characters. | | **Output field** | A new field. It must not exist yet. | Tag names are written without `payload.` and must be required by the source or produced by an earlier node. Division by zero, a missing value or a result that is not a finite number goes to **error**. The result is a number of quality Good. ### Expression **T A**. The same node as **Calculate**, with the same settings. ### Set Unit **T A**. Settings **Field** and **Unit**, picked from the unit catalog (type part of a name, such as `Celsius` or `pressure`). ### Set Quality **T A**. Settings **Field** and **Quality**: Good, Bad or Uncertain. Later nodes that calculate refuse values that are not Good. ### Add Context **T A**. Adds facts about the device as attributes (`attributes.site`, ...). Setting **Context to add**: enterprise, site, area, line, equipment, device name, profile, protocol. Facts that are empty for the device are skipped. ## Window and state These nodes remember earlier values, separately for each device. ### Moving Average **T A**. The average of the last readings. Settings **Input field**, **Output field**, **Window samples** (1 to 1024, default 8). ### Rate Of Change **T A**. Change per second since the previous reading. Settings **Input field**, **Output field**. The first reading only starts the count and goes to **error**. ### Event Time Window Panel name **Time window average**. **A**. The average over a time span. Settings **Input field**, **Output field**, **Duration (ms)** (default 60000), **Maximum samples** (1 to 1024, default 128). A reading older than the window goes to **error**. ### Latest Join Panel name **Combine**. **A**. Puts the latest values of two devices side by side, for example inlet and outlet pressure on one line. | Setting | Values | | --- | --- | | **Pair values from** | The same device, equipment, line / cell, area or site. | | **First value**, **Store first as** | The first tag and the field it is stored in. | | **Second value**, **Store second as** | The second tag and its field. | | **At most this far apart (ms)** | Default 1000. | | **Roles (advanced)** | **First role**, **Second role**: which device plays which part. | Inputs **left** and **right**. Until both values are known and close enough in time, readings go to **error**. ### Debounce **A**. Lets through at most one reading per device in each **Quiet period (ms)** (default 1000). The others go to **error**. ### Hysteresis Panel name **Band**. **A**. Turns a value into an open or closed state with a dead band, so it does not flicker around one threshold. Settings **Input field**, **Open at or above** (default 60), **Close at or below** (default 40). Outputs **open** and **closed**. ### Detect Anomaly Panel name **Detect unusual values**. **A**. Compares each value with the average and spread of the recent values. | Setting | Values | | --- | --- | | **Value** | The tag. | | **Learn from the last values** | 10 to 1024. Default 120. | | **Sensitivity** | In standard deviations, 1 to 10. Default 3. Higher means fewer findings. | | **Values before judging (warm-up)** | At least 5, at most the window. | Outputs **unusual** and **normal**. During warm-up every value is normal. ### Summarize Panel name **Summarize per period**. **A**. One result per period. | Setting | Values | | --- | --- | | **Value** | The tag. | | **Summary** | average, lowest value, highest value, sum of values, number of values, change of a counter, total over time (value × hours). | | **Period** | 15 minutes, 30 minutes, hour, 4 hours, shift (8 hours), 12 hours, day. | | **Result field**, **Time zone** | | Outputs **period** (once, when the first value of the next period arrives) and **collecting** (every other value). A value older than the current period is ignored. ## Route ### Switch **T A**. Sends data to **true** or **false**. **Condition type**: - **Numeric comparison**: **Input field**, **Operator** (`>`, `>=`, `<`, `<=`, `==`, `!=`), **Threshold**. - **Conditions (all / any)**: the same conditions as **Filter**. In a pipeline that runs after data is stored, a switch can also have a lasting time: it sends data to **true** only once its condition has held for that long without a break, on each device. The **Conditions** step of the builder sets it ("once that has lasted … s"). Use it where a start-up surge or a noisy value would otherwise raise an alarm. ### Split **T**. Copies the data into **Branches** parallel branches (2 to 16). Outputs **branch 1** to **branch N**. ### Drop Panel name **Stop**. **T**. Ends the branch; the data goes no further. Setting **Operational reason**. ### Quarantine **T**. Takes suspicious data out of normal processing so it can be inspected. Setting **Operational reason**. Ends the branch. ### Transport Output Panel name **Continue**. **T**. Sends the processed data on to storage and outbound targets. Ends the branch. ### Alarm Status Route Panel name **Alarm status**. **A**. Sends data to **true** or **false** depending on an alarm of this pipeline for the device. **Take TRUE when the alarm is**: **Open**, **Closed (or never opened)** or **Open and acknowledged on the hub**. **Alarm**: one alarm key, or any alarm of this pipeline. ## Automation ### Create Or Update Alarm Panel name **Open alarm**. **A**. Opens an alarm, or updates it if it is already open. Ends the branch. | Setting | Values | | --- | --- | | **Alarm key** | A short name; **Clear Alarm** uses the same key. | | **Severity** | Info, Warning (default), Critical. | | **Message** | Up to 512 characters. | | **Entity key** | What the alarm is about. Default `device.id`. | ### Clear Alarm **A**. Closes an alarm opened earlier in this pipeline. **Alarm to clear** picks one of the pipeline's alarm keys. Ends the branch. ### Notification Panel name **Notify**. **A**. Sends **Message** through a **Notification channel**. Ends the branch. See [Notification channels](https://proxus.io/docs/reference/notification-channels). ## Effects Effects reach outside Proxus. They run only when the pipeline is published in **Active** mode; in **Shadow** mode they are recorded as "would" actions. **Send to target**, **Write to device** and **Call an API** also need `[Flows] EffectsEnabled = true` on the gateway; see [Configuration keys](https://proxus.io/docs/reference/configuration#flows). ### Target Output Panel name **Send to target**. **A**. Sends the data to outbound targets. Ends the branch. | Setting | Values | | --- | --- | | **Targets** | **Current device targets**, **Specific outbound channel** (then **Outbound channel**) or **Platform storage only (store as tag)**. | | **Minimum interval (ms)** | 100 or more. Default 1000. | This is an extra delivery: the device's normal delivery to its targets continues. ### Device Write Panel name **Write to device**. **A**. Writes a value to a device's tag. Ends the branch. | Setting | Values | | --- | --- | | **Device** | **Ingress device** (the device the data came from) or **Specific device** (then **Fixed device**). | | **Writable register** | A tag that is not read-only. | | **Value field** | The field holding the value. | | **Minimum**, **Maximum** | Values outside this range are not written and go to **error**. | | **Minimum interval (ms)** | Default 1000. | A write is tried once, with a 10-second limit. A write that timed out is not repeated. ### Call Api Panel name **Call an API**. **A**. Fetches one value from a REST API target and stores it as a tag of a device. Ends the branch. | Setting | Values | | --- | --- | | **API connection** | An outbound target of type **REST API**. | | **Device** | The device the value is stored on. | | **Path (optional)** | Added to the target's address; starts with `/` or `?`. It cannot change the host. | | **Value in the response** | Where the value is in the answer, for example `data.items[0].price`. | | **Store as tag** | The tag name. | Each call has a 20-second limit. ## Observe ### Capture Sink Panel name **Trace**. **T A**. Keeps a short live sample of the data for the **Trace** tab. Setting **Trace label**. ### Error Sink Panel name **Errors**. **T A**. Collects and counts data that failed a step. Connect **error** outputs to it. ## Limits of a pipeline | Limit | Value | | --- | --- | | Nodes | 1 to 128 | | Connections | 256 | | Size of the definition | 256 KB | | Sources in an automation pipeline | 8 | | Branches from one node | 16 | | Window size of a node | 1024 values | | Pipelines on one gateway | 256 | | Name | 1 to 120 characters | The graph may not loop back, and every node must be reachable from a source. The **Trace** tab keeps the last 64 items per pipeline. ## Related - [Pipelines](https://proxus.io/docs/automate/pipelines): build, test and publish. - [Pipelines and rules](https://proxus.io/docs/concepts/pipelines-and-rules): when to use which. - [Troubleshoot automation](https://proxus.io/docs/troubleshoot/automation). --- # Configuration keys > Every section and key of Proxus-config.toml with its default and meaning, how to set it as an environment variable, and which keys have no effect. Source: https://proxus.io/docs/reference/configuration The hub and every edge gateway read their settings from `Proxus-config.toml`. This page lists every section and key of the delivered file. How to edit settings from the hub's screens is in [Configuration](https://proxus.io/docs/administer/configuration). ## Where the file is and how it is read - Installed directly on a machine, the file is next to the program. In a container it is in `/app/config/` (the `config` volume of the delivered Docker Compose file). If it is missing, the delivered file is written there at first start. - The hub reads keys that concern the hub, a gateway reads keys that concern gateways. The **Read by** column says which. The hub runs its own gateway (**SYSTEM**), which reads the gateway keys from the same file. - A setting is read at start. Restart the hub or gateway after a change. ## Environment variables Every key can also be set with an environment variable, which wins over the file. Join the section and the key with two underscores: | In the file | Environment variable | | --- | --- | | `[NATS]` `BrokerUrl` | `NATS__BrokerUrl` | | `[UNS.Optimizations]` `SummaryIntervalMs` | `UNS__Optimizations__SummaryIntervalMs` | | `[Security]` `Lockout.Enabled` | `Security__Lockout__Enabled` | | `[[WEBAPI.Authentication.Jwt]]` `IssuerSigningKey` | `WEBAPI__Authentication__Jwt__0__IssuerSigningKey` | | `[MCP]` `IPWhitelist = ["10.0.0.0/8"]` | `MCP__IPWhitelist__0=10.0.0.0/8` | | `[Service]` `UI-Port` | `Service__UI-Port` | One environment variable has no key in the file: `PROXUS_CERTIFICATE_STORE_KEY`, the key that decrypts the private keys in the [Certificate Store](https://proxus.io/docs/administer/certificates) (a base64 value of 32 bytes). Without it, the hub keeps this key in `keys/STORE/certificate-store.key` in the config folder. Back up either one with the config folder. Names are not case-sensitive. Lists take an index (`__0`, `__1`). Keys with a hyphen, such as `UI-Port`, work in a Docker Compose or Kubernetes `environment` block; a Linux shell cannot `export` them. > **Warning:** Programs can also be started with `Key=value` arguments (for example `./Proxus.Server GatewayID=2`). Such an argument is written into the configuration file and stays there, and it changes every line in the file that starts with that key, in any section. Prefer environment variables. The form `--Key=value` has no effect. Keys marked **Not used** are in the file but change nothing in this release. ## Culture | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `Name` | `"tr-TR"` | hub, gateway | The default language and number and date format, as a culture name such as `en-US`. Users can switch language in the hub when it is one of `Languages` (see [Language](#language)). | ## Kestrel.EndpointDefaults | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `Protocols` | `"Http1AndHttp2"` | | **Not used**: each port sets its HTTP versions itself. | ## NATS The message bus between the hub and the gateways. Every connection to the hub's NATS server uses TLS and checks the server against the platform CA. | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `BrokerUrl` | `"nats://localhost:4222"` | hub, gateway | The NATS server address. In the delivered Docker installation: `nats://hub-server:4222`. | | `BrokerUser` | `"acc"` | gateway | User name, when no credentials file is set. | | `BrokerPassword` | `"acc"` | gateway | Password, when no credentials file is set. | | `CredsFile` | `""` | gateway | Path to the gateway's NATS credentials file. Replaces user and password. Gateways installed from the hub get one. | | `CaFile` | `""` | gateway | The CA file the NATS server is checked against. Empty: the file the hub writes next to the credentials file. Set it only to use another path. | | `TlsHostNames` | not set | hub | Extra names the hub's NATS server is reached by, separated by commas, for example `"nats.plant.example"`. The certificate also covers `hub-server`, the hub machine's names and addresses, every address an edge install command is created for, and `[Service] PublicHostNames`. | | `ServerTrustDir` | not set (`"/nats-config/nats"`) | hub | The folder where the NATS server itself finds its certificate, as that server sees it. Change it only if the NATS server mounts the trust folder elsewhere. | ## Flows The pipeline engine on each gateway. See [Pipeline nodes](https://proxus.io/docs/reference/pipeline-nodes). | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `EffectsEnabled` | `false` | gateway | Allows pipelines in **Active** mode to write to devices, call APIs and send to targets. With `false` these effects are refused. | | `Workers` | `0` | gateway | Pipeline workers. `0` picks the number of processor cores, at most 4. Range 1 to 4. | | `QueueCapacity` | `256` | gateway | Events waiting for a worker (16 to 4096). | | `EffectQueueCapacity` | `128` | gateway | Effects waiting to run (16 to 4096). A full queue refuses new effects. | | `CheckpointIntervalSeconds` | `30` | gateway | How often pipeline state (windows, alarms) is saved to disk (5 to 3600). | | `StatusIntervalSeconds` | `5` | gateway | How often the gateway reports pipeline status to the hub (1 to 300). | ## Service | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `UI-Port` | `"8080"` | hub | The hub's HTTP port: screens, REST API, Telemetry API and MCP. | | `UI-HTTPS-Port` | `"8443"` | hub | The hub's HTTPS port, with the default certificate from the [Certificate Store](https://proxus.io/docs/administer/certificates). An empty value turns HTTPS off. `UI-Port` stays on for local access. | | `RedirectHttpToHttps` | not set (`"false"`) | hub | `"true"` sends every HTTP request to HTTPS and turns on HSTS. Off by default, because HSTS makes browsers use HTTPS on every port of the host. | | `PublicHttpsPort` | not set | hub | The port others reach HTTPS on, when it is published on another port of the host. | | `PublicHostNames` | not set | hub | Extra names and addresses of the hub, separated by commas, for example `"proxus.plant.example, 203.0.113.10"`. The hub's HTTPS certificate (on new installations, or after **Renew**) and its NATS certificate cover them, next to the machine's own names and addresses. | | `Server-Port` | `"8083"` | gateway | The gateway's HTTP port: health check and [historical import](https://proxus.io/docs/develop/historical-import). | | `Server-HTTPS-Port` | not set | gateway | Set it to also serve HTTPS on the gateway, with the gateway's certificate from the hub. | | `Name` | `"Proxus"` | | **Not used.** | | `UI-Address` | `"localhost"` | | **Not used.** | | `Server-Address` | `"localhost"` | | **Not used.** | ## UI | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `ForceSkiaRendering` | `true` | hub | Drawing engine for dashboard and report images, on Windows only. | | `EnableDashboardExportRestrictedMode` | `false` | hub | Restricted mode for dashboard export. Must be present in the file. | | `EnableDashboardCustomPalette` | not set | hub | A list of colors for dashboard charts, for example `["#315b50", "#c46b2e"]`. | ## Security | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `Lockout.Enabled` | `true` | hub | Lock a user out after failed sign-ins. | | `Lockout.MaxFailedAccessAttempts` | `3` | hub | Failed sign-ins before the lockout. | | `Lockout.DefaultLockoutTimeSpan` | `30` | hub | Length of the lockout, in seconds. | ## Security.Password Rules for passwords. They are checked when a user must choose a new password at sign-in, when a user changes their own password with **Change My Password**, and when an administrator uses **Reset Password**. Restart the hub after a change. | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `MinLength` | `6` | hub | Shortest password. | | `MaxLength` | `128` | hub | Longest password. | | `RequireUppercase` | `0` | hub | At least this many capital letters. | | `RequireLowercase` | `0` | hub | At least this many small letters. | | `RequireDigits` | `0` | hub | At least this many digits. | | `RequireSpecialCharacters` | `0` | hub | At least this many characters from `AllowedSpecialCharacters`. | | `AllowedSpecialCharacters` | `"!@#$%^&*()_+-=[]{}\|;:,.<>?"` | hub | What counts as a special character. | | `PreventKeyboardPatterns` | `false` | hub | Refuse keyboard rows such as `qwerty`. | | `PreventRepeatedCharacters` | `false` | hub | Refuse a character repeated more than `MaxRepeatedCharacters` times in a row. If the key is removed from the file, this check is on. | | `MaxRepeatedCharacters` | `3` | hub | See above. | | `PasswordHistory` | `5` | hub | A user cannot choose any of their last N passwords again; the current one counts. `0` turns it off. | | `PasswordExpirationDays` | `90` | hub | After this many days the user must choose a new password at the next sign-in. `0`: passwords do not expire. After an upgrade, the age of existing passwords starts at the first start of the new version. | | `PasswordExpirationWarningDays` | `14` | hub | The user sees a warning at sign-in this many days before the password expires. `0`: no warning. | | `PreventCommonPasswords` | `true` | hub | Refuse the most common passwords and passwords that contain the user name. | | `RequireChangeOnFirstLogin` | `true` | hub | New users created on **Security > Users** start with **Force Password Change** ticked. | | `TempPasswordExpirationHours` | `24` | hub | A password set with **Reset Password** stops working if the user has not replaced it within this many hours; an administrator then resets it again. `0`: no limit. | ## Rules.DeviceNaming A naming rule for new devices. See [Add a device](https://proxus.io/docs/connect/devices/add-a-device). | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `Enabled` | `false` | hub | Check device names against `Pattern`. | | `Pattern` | `""` | hub | A regular expression the whole name must match, for example `^[A-Z]{3}_[A-Z0-9_]+$`. | | `Hint` | `""` | hub | The message shown when a name does not match. | | `[[Rules.DeviceNaming.Sites]]` `Site`, `Pattern`, `Hint` | not set | hub | A different pattern for the devices of one site. | ## Data | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `MaxDeviceDataLoad` | `1000` | hub | Most rows of device data loaded at once in the hub's screens. | | `DeviceDataTimeRange` | `"1h"` | hub | Default time span of device data in the screens. Values like `30s`, `15m`, `1h`, `7d`, `4w`, `6mo`, `1y`. | | `LogsTimeRange` | `"1d"` | hub | Default time span of logs in the screens. | ## EdgeGateway | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `GatewayID` | `"1"` | gateway | The gateway's ID in the hub. `1` is the hub's own gateway, **SYSTEM**. | | `GatewayName` | `"SYSTEM"` | gateway | The gateway's name. | | `EdgeMode` | `"Proxus"` | gateway | `Proxus`: managed by a hub (the normal case). `Standalone`: runs without a hub and sends to an MQTT broker set in `[MQTTAPI]`. | | `Integration` | `"MQTT_CLIENT"` | gateway | The connection used in `Standalone` mode. | | `EdgeMetricsTransmissionInterval` | `10` | gateway | Seconds between two reports of the gateway's metrics to the hub. | ## ClickHouse The database that stores tag values and logs. | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `ClickHouseHost` | `"clickhouse"` | hub, gateway | Host name. | | `ClickHousePort` | `8123` | hub, gateway | HTTP port. | | `ClickHouseMySqlPort` | `9004` | hub | MySQL-protocol port, used by reports. | | `ClickHouseDatabase` | `"proxus"` | hub, gateway | Database name. | | `ClickHouseUsername` | `"admin"` | hub, gateway | User. | | `ClickHousePassword` | `"proxus"` | hub, gateway | Password. Change it together with the database's own setting. | | `ClickHouseWriteIntervalSeconds` | `1` | gateway | Seconds between two writes of buffered values. | | `ClickHouseLogTTLExpression` | `"toDateTime(Time) + INTERVAL 45 DAY DELETE"` | gateway | How long logs are kept. | | `ClickHouseTTLExpression` | not set | gateway | How long tag values are kept, for example `"toDateTime(Time) + INTERVAL 1 YEAR DELETE"`. Not set: kept forever. | ## Reports.ClickHouse and Reports.PostgreSqlFederation | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `[Reports.ClickHouse]` `Enabled` | `true` | hub | Offer the tag value database as a data source in [reports](https://proxus.io/docs/analyze/reports). | | `[Reports.PostgreSqlFederation]` `Enabled` | `true` | hub | Set up the read-only reporting access described in [Reporting federation](https://proxus.io/docs/analyze/reporting-federation). | ## ScheduledDelivery See [Scheduled delivery](https://proxus.io/docs/analyze/scheduled-delivery). | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `ExternalDeliveryEnabled` | `true` | hub | Allow scheduled reports to be sent by email. With `false`, nothing leaves the hub. | | `AutomaticRetryEnabled` | `false` | hub | Allow schedules to retry a failed delivery. | | `ArtifactRetentionDays` | `0` | hub | Delete generated files older than this many days (0 to 3650). `0` keeps them. | | `ArtifactCleanupIntervalHours` | `24` | hub | How often old files are deleted (1 to 168). | ## Database | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `ConnectionString` | `"Server=postgresql;Port=5442;User ID=proxus;Password=proxus;Database=proxus;..."` | hub, gateway | The PostgreSQL database that holds the configuration (devices, users, rules). | | `TelemetryDB` | `"clickhouse"` | hub, gateway | Where tag values are stored. Keep `clickhouse`. | | `InsertStrategy` | `"Bulk"` | hub | How values are written. Must be present. | | `BulkInsertInterval` | `1000` | hub | Milliseconds values are collected before one write. | | `MaxConcurrentInserts` | `16` | hub | Parallel writers to the database. | | `EnableDataStoreCache` | `false` | hub | Cache configuration reads in memory. | | `TablesExcludedFromCache` | `["DeviceRawData", "Log", "Device"]` | hub | Tables never cached. | | `DeviceRawDataRetentionPolicy` | `"0s"` | | Has no effect with `TelemetryDB = "clickhouse"`. Use `ClickHouseTTLExpression`. | ## Fieldbus How the gateway reads devices. | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `UseBatchReadForSupportedProtocols` | `true` | gateway | Read neighboring addresses in one request where the protocol allows it. | | `UseS7DbFullRead` | `true` | gateway | Siemens S7: read a whole data block in one request. | | `SleepProbeIntervalMs` | `10000` | gateway | When a device stops answering it goes to sleep mode; the first retry comes after this many milliseconds. | | `SleepProbeMaxIntervalMs` | `300000` | gateway | Retries slow down up to this interval. | | `MaxConsecutiveLocalOverloads` | `3` | gateway | How many read timeouts caused by an overloaded gateway (not by the device) are ignored before they count against the device. `0` turns this off. | ## Browse Browsing and discovery in the device setup wizard. | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `UseEdgeRemoteBrowse` | `true` | hub | Browse from the device's gateway, not from the hub. | | `OpcUaDiscoveryPorts` | `"tcp:4840, tcp:53530, https:53443"` | hub | Ports tried when searching for OPC UA servers. | | `OpcUaSeedDiscoveryUrls` | `""` | hub | Discovery URLs always tried, separated by commas. | | `OpcUaDiscoveryMaxHosts` | `"254"` | hub | Most addresses scanned. | | `OpcUaDiscoveryProbeTimeoutMs` | `"150"` | hub | Wait per address. | | `OpcUaDiscoveryProbeParallelism` | `"48"` | hub | Addresses tried at the same time. | | `MtConnectDiscoveryPorts` | `"5000, 5001, 5005, 5006, 7000"` | hub | Ports tried when searching for MTConnect agents. | | `MtConnectDiscoveryMaxHosts` | `"254"` | hub | Most addresses scanned. | ## MQTTBroker The broker on each gateway. See [MQTT and the UNS topics](https://proxus.io/docs/develop/mqtt). | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `Enabled` | `true` | gateway | Run the broker and publish the UNS topics. | | `MQTTBrokerPort` | `1883` | gateway | The broker port without TLS. | | `TlsPort` | `8883` | gateway | The broker port with TLS, using the gateway's certificate from the hub. It opens once the hub has issued the certificate. `0` turns TLS off. Devices check the broker against the platform CA. | | `PlainEnabled` | `true` | gateway | Keep the port without TLS open. `false` accepts TLS only. | | `AllowAnonymous` | `false` | gateway | Accept clients without a user name. | | `MasterToken` | `""` | gateway | The user name for UNS clients. Created at first start when empty. | | `EnableMQTTHooks` | `true` | gateway | Publish the values the gateway reads on the UNS topics. | | `AllowPortFallback` | not set (`true`) | gateway | When the port is taken, use a free one instead of failing. | | `BrokerHostAddress` | `"127.0.0.1"` | | **Not used.** | ## UNS and UNS.Optimizations | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `UNSPayloadFormat` | `"JSON"` | gateway | `JSON` or `SparkplugB`. | | `UNSGroupId` | `"ProxusGroup"` | gateway | Sparkplug group ID. | | `UNSEdgeNodeId` | `"ProxusEdge"` | gateway | Sparkplug edge node ID. | | `UNSRetainMessages` | `true` | gateway | Retain the state topics. | | `UNSVersion` | not set (`"v1"`) | gateway | First level of every UNS topic. | | `QoS.Telemetry`, `QoS.State`, `QoS.Command` | not set (`0`, `1`, `1`) | gateway | MQTT QoS per kind of message. | | `[UNS.Optimizations]` `TelemetryThinPayload` | `true` | gateway | Leave the `context` object out of each tag message. | | `SummaryIncludeContext` | `true` | gateway | Put the place of the device in the `_summary` message. | | `SummaryIntervalMs` | `5000` | gateway | Least time between two summaries of a device. `0`: every reading. | | `LastSeenIntervalMs` | `5000` | gateway | Least time between two `_lastSeen` messages. | | `StatusOnChangeOnly` | `true` | gateway | Publish `_status` only when it changes. | | `SummaryOnlyOnChange` | `false` | gateway | Publish a summary only when a value changed. | ## MQTTAPI Only for a gateway with `EdgeMode = "Standalone"`: the MQTT broker it sends its data to. | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `MQTTServer` | `"your.mqtt.server.address"` | gateway | Broker host. | | `MQTTPort` | `1883` | gateway | Broker port. | | `MQTTUser`, `MQTTPassword` | placeholders | gateway | Credentials. | | `MQTTVersion` | `"V310"` | gateway | `V310` or `V500`. | | `MQTTConnectionTimeOut` | `30` | gateway | Seconds. | | `MQTTKeepAlivePeriod` | `60` | gateway | Seconds. | | `MQTTCleanSession` | `true` | gateway | | ## WEBAPI `[[WEBAPI.Authentication.Jwt]]`: the tokens of the [REST API](https://proxus.io/docs/develop/rest-api). Only the first entry is used; its environment variables start with `WEBAPI__Authentication__Jwt__0__`. | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `Issuer` | `"My"` | hub | Written into and checked on every token. | | `Audience` | `"http://0.0.0.0:8082"` | hub | Written into and checked on every token. | | `IssuerSigningKey` | `""` | hub | The secret tokens are signed with. Leave it empty: the hub then makes a random key on its first start and keeps it in `Keys/UI/jwt-signing.key` in the shared configuration folder. A value shorter than 32 characters, or the example key of earlier versions, is not used. Changing it makes all issued tokens invalid. | | `TokenExpireTime` | `"1y"` | hub | How long a token is valid: `30m`, `2h`, `7d`, `1y`. | ## Cluster | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `RedisConnection` | not set | hub | A Redis server, for example `redis:6379`, shared by several hub instances (MCP sign-ins). | | `GrpcInterfaceBinding`, `ClusterProvider` | `"AdvertisedHost"`, `"Consul"` | | **Not used**: read, but the setting is not applied. | | `IdentityLookupStrategy`, `HeartbeatExpiration`, `ActorRequestTimeout`, `ActorActivationTimeout`, `GossipRequestTimeout`, `ActorSpawnVerificationTimeout` | see file | | **Not used.** | ## UserFunctions See [Functions SDK](https://proxus.io/docs/develop/functions-sdk#logging-and-failures). | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `ExceptionThresholdPerFunction` | `10` | gateway | Unhandled exceptions before a function is undeployed. `0`: no limit. | | `UseAutoTryCatchInjector` | `true` | gateway | Wrap function code so exceptions are logged and counted. | | `UseAutoDisposeInjector` | `false` | gateway | Experimental: dispose objects the function no longer uses. | | `LogLevelPolicy` | `["Error:2 1m", "Critical:2 1m"]` | gateway | Most log lines per level and window for each function. | ## Logging | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `Loglevel` | `3` | hub, gateway | Lowest level written: `0` Trace, `1` Debug, `2` Information, `3` Warning, `4` Error, `5` Critical. | | `LogRetentionTime` | `14` | hub | Days logs are kept in the database. | | `LogToFile` | `true` | hub, gateway | Also write logs to files in the `config` folder. | | `IncludeDiagnosticDetails` | `false` | hub, gateway | Add technical details to log entries. | | `OperationalLogDedupeWindowSeconds` | `60` | hub, gateway | The same message within this time is counted, not written again. | | `LogSqlQueries` | `false` | | **Not used.** | ## Tracing, Metrics and Otlp | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `[Tracing]` `Enable` | `false` | hub, gateway | Send traces over OpenTelemetry. | | `[Metrics]` `Enable` | `false` | hub, gateway | Send metrics over OpenTelemetry, and serve them for Prometheus on the gateway. | | `[Otlp]` `Endpoint` | `"http://otel-collector:4317"` | hub, gateway | The OpenTelemetry collector. | | `[Otlp]` `MetricsIntervalMilliseconds` | `10000` | hub, gateway | How often metrics are sent. | | `[Otlp]` `SkipWhenEndpointUnresolvable` | `true` | hub, gateway | Do not export when the collector's name cannot be resolved. | ## Language The language list of the hub. The section name is shown as it appears in the file: ```toml [DevExpress.ExpressApp] Languages = "en-US;tr-TR" # languages users can switch between ShowLanguageSwitcher = true # show the language switcher ``` The look of the hub is not a setting: Proxus has one theme. To show your company's name and logo, use [White labeling](https://proxus.io/docs/administer/white-labeling). A theme section that an earlier version wrote into the file is removed on the first start, after a backup (`Proxus-config.toml.pre-proxus-theme.bak`). ## Runtime | Key | Default | Read by | Meaning | | --- | --- | --- | --- | | `MinWorkerThreads` | `0` | gateway | Threads kept ready. `0`: four per core, at least 32. | | `MinCompletionPortThreads` | `0` | gateway | Threads kept ready for network work. | | `ThreadPoolLatencyWarningMs` | `500` | gateway | Log a warning when the gateway is this late in starting work. | | `ThreadPoolSampleIntervalMs` | `250` | gateway | How often that delay is measured. | | `ThreadPoolStarvationCorrelationWindowMs` | `5000` | gateway | How long a read timeout is blamed on an overloaded gateway after a warning. | ## MCP and MCP.ClickHouse See [MCP server](https://proxus.io/docs/develop/mcp#secure-it-for-production) for every key and its meaning. Two keys there are **Not used**: `AlertOnSuspiciousActivity` and `[MCP.ClickHouse]` `DefaultHours`. `[MCP.ClickHouse]` `MaxHours` is only checked to be above zero. ## Keys read but not in the file These keys are read with the default shown when they are absent. Add them to the right section to change them: `[MQTTBroker] AllowPortFallback` (true), `[UNS] UNSVersion` ("v1"), `[UNS] QoS.Telemetry` (0), `QoS.State` (1), `QoS.Command` (1), `[Fieldbus] LogTelegramMetrics` (true), `[Cluster] RedisConnection`, `[MCP] RedisConnection`, `[HistoricalImport] Enabled` (false) and `StorageEnabled` (false), `[Service] Server-HTTPS-Port`, `[ClickHouse] ClickHouseTTLExpression`, `[Flows] StatePath`. ## Related - [Configuration](https://proxus.io/docs/administer/configuration): the Configuration screen. - [Network ports and endpoints](https://proxus.io/docs/reference/ports) - [Docker](https://proxus.io/docs/operate/docker): setting environment variables in the compose file. --- # Network ports and endpoints > Every port the hub, the edge gateways and the services of the Docker installation listen on, and the HTTP endpoints behind them. Source: https://proxus.io/docs/reference/ports This page lists what each part of a Proxus installation listens on, with the default port from the configuration file and the delivered Docker Compose file. Use it to write firewall rules. Which of these must be reachable from outside the host is in [Security hardening](https://proxus.io/docs/operate/security). ## Hub | Port | Protocol | Setting | Used by | | --- | --- | --- | --- | | 8443 | HTTPS | `[Service] UI-HTTPS-Port` | Browsers, API clients, MCP clients, gateway installation. On by default; an empty value turns it off. | | 8080 | HTTP | `[Service] UI-Port` | The same, unencrypted, for local access. `[Service] RedirectHttpToHttps = "true"` sends it to HTTPS. | | 4222 | NATS over TLS | `[NATS] BrokerUrl` | The hub's own processes and the **SYSTEM** gateway. | | 7422 | NATS over TLS | | Edge gateways on other machines. | | 6222 | NATS over TLS | | Kubernetes HA only: the NATS servers of the cluster connect to each other by pod name. | | 8222 | HTTP | | NATS monitoring. Internal. | The NATS ports belong to the hub's message server (`hub-server`). Every NATS connection checks the server's certificate against the platform CA. See [Certificates](https://proxus.io/docs/administer/certificates). Endpoints on the hub's HTTP and HTTPS ports: | Path | What it is | Sign-in | | --- | --- | --- | | `/` | The hub's screens. | user | | `/api/Authentication/Authenticate` | Gets a token. See [REST API](https://proxus.io/docs/develop/rest-api). | none | | `/api/odata/...` | Read and change objects. | token or browser session | | `/api/Telemetry/execute` | Query stored values. See [Telemetry API](https://proxus.io/docs/develop/telemetry-api). | token | | `/swagger` | The interactive API description; `/swagger/v1/swagger.json` is the OpenAPI file. | none to view | | `/mcp` | The MCP server for AI assistants. See [MCP server](https://proxus.io/docs/develop/mcp). | sign-in inside MCP | | `/edge/` | The install script of a new gateway, valid once and for one hour. See [Install a gateway](https://proxus.io/docs/connect/edge-gateways/install-a-gateway). | the token in the address | | `/edge/uninstall/` | The removal script of a gateway. | none | | `/healthz` | Answers `Healthy` when the hub is running. For load balancers and container health checks. | none | | `/metrics` | Metrics for Prometheus, only when `[Metrics] Enable` or `[Tracing] Enable` is `true`. | none | ## Edge gateway Every gateway, including the hub's own **SYSTEM** gateway, listens on: | Port | Protocol | Setting | Used by | | --- | --- | --- | --- | | 8883 | MQTT over TLS | `[MQTTBroker] TlsPort` | UNS subscribers and devices that publish their own values, encrypted with the gateway's certificate. Opens once the hub has issued the certificate. `0` turns it off. See [MQTT and the UNS topics](https://proxus.io/docs/develop/mqtt). | | 1883 | MQTT | `[MQTTBroker] MQTTBrokerPort` | The same, without TLS, for devices that cannot use it. `[MQTTBroker] PlainEnabled = false` closes it. | | 8083 | HTTP | `[Service] Server-Port` | Health checks and historical import. | | not set | HTTPS | `[Service] Server-HTTPS-Port` | The same, encrypted with the gateway's certificate from the hub, when you set a port. | Endpoints on the gateway's HTTP port: | Path | What it is | Sign-in | | --- | --- | --- | | `/healthz` | Answers `Healthy` when the gateway is running. | none | | `/api/v1/devices//historical/batches` | Historical import. See [Historical import](https://proxus.io/docs/develop/historical-import). | the device's token in `X-IoT-Token` | | `/metrics` | Metrics for Prometheus, only when `[Metrics] Enable` or `[Tracing] Enable` is `true`. | none | A gateway opens connections itself: to the hub's NATS server over TLS (a gateway installed from the hub uses the leaf port 7422; the hub's own gateway uses 4222), to the hub on 8443 during installation, to the devices it reads, and to its outbound targets. Devices and targets do not connect to the gateway, except devices that publish to its broker. A gateway installed from the hub publishes 8883, 1883 and its service port (8083) on its host. ## Services in the Docker installation The delivered `docker-compose.yml` publishes these ports on the host: | Container | Port on the host | What it is | | --- | --- | --- | | `proxus-ui` | 8080, 8443 | The hub, over HTTP and HTTPS. | | `proxus-server` | 8083, 1883, 8883 | The hub's gateway (**SYSTEM**): HTTP, MQTT and MQTT over TLS. | | `hub-server` | 4222 | NATS over TLS, the message bus between the hub and its own gateway. | | `hub-server` | 7422 | NATS leaf connections over TLS: gateways on other machines connect here. | | `hub-server` | 8222 | NATS monitoring page (HTTP). | | `postgresql` | 5442 | PostgreSQL, the configuration database. | | `clickhouse` | 8123 | ClickHouse over HTTP, the database of tag values and logs. | | `clickhouse` | 9000 | ClickHouse native protocol. | | `clickhouse` | 9004 | ClickHouse MySQL-compatible protocol, used by reports. | | `clickhouse` | 9005 | ClickHouse PostgreSQL-compatible protocol. | > **Warning:** Only 8443 has to be reachable by users, and 7422 and 8443 by gateways on other machines. Keep the database ports (5442, 8123, 9000, 9004, 9005), 4222 and 8222 closed to everything but the host, or remove them from the compose file if nothing outside the host needs them. ## Ports the gateway connects to When you leave **Port** empty on a device, the gateway uses the protocol's usual port, for example 502 for Modbus TCP, 102 for Siemens S7 and 44818 for EtherNet/IP. The full list is in [Protocols](https://proxus.io/docs/reference/protocols). ## Related - [Configuration keys](https://proxus.io/docs/reference/configuration) - [Docker](https://proxus.io/docs/operate/docker) - [Security hardening](https://proxus.io/docs/operate/security) --- # Glossary > The words the Proxus hub uses for its building blocks, screens and states, each explained in one or two plain sentences. Source: https://proxus.io/docs/reference/glossary Terms are listed in alphabetical order and written the way the hub writes them. ## A | Term | Meaning | | --- | --- | | **Active** (pipeline) | A pipeline published so that its effects really happen: alarms open, messages are sent, devices are written. Compare **Shadow**. | | **Address** (tag) | Where a value is in the machine: a register number, a PLC tag name, an OPC UA node. The form depends on the protocol. | | **Alert** | A record that a rule or pipeline found a condition, such as a value over a limit. It has a severity and a status: **New**, **Acknowledged**, **Resolved** or **Ignored**. Alerts are listed in [Alerts](https://proxus.io/docs/monitor/alerts). | | **Application Templates** | Packages of devices, profiles, pipelines and dashboards that set up a ready-made solution. See [App templates](https://proxus.io/docs/organize/app-templates). | | **Area** | The third level of the plant hierarchy, below **Site**: a hall, a department, a utility. | ## B | Term | Meaning | | --- | --- | | **Bad** (quality) | A value that cannot be trusted: the read failed or the device reported it as wrong. Shown in red; a rule or pipeline can leave it out. | | **Browse** | Asking a device for the list of values it offers, so you can pick tags instead of typing addresses. Available for OPC UA, SNMP, MTConnect and Allen Bradley. | ## C | Term | Meaning | | --- | --- | | **Certificate pinning** (install command) | The edge install command accepts only the hub that holds a known HTTPS key (`--pinnedpubkey`), so the installer cannot be swapped on the way. If the hub's HTTPS certificate changes, create a new command. See [Install a gateway](https://proxus.io/docs/connect/edge-gateways/install-a-gateway). | | **Certificate Store** | The place in the hub (**Security > Certificate Store**) where every certificate is kept: for HTTPS, the message server, the gateways, OPC UA and outbound targets. It is also the platform's certificate authority. See [Certificates](https://proxus.io/docs/administer/certificates). | | **Connection test** | A check, run from the gateway, that the gateway can reach a device and open a protocol session with it. | ## D | Term | Meaning | | --- | --- | | **Data type** | The kind of value a tag holds: `Bool`, `Short`, `UShort`, `Int`, `UInt`, `Float`, `Long`, `ULong`, `Double`, `String`, `Bytes`, `DateTime`. | | **Device** | One machine, PLC, robot or sensor that Proxus reads. It belongs to one edge gateway and uses one device profile. | | **Device Profile** | How to talk to a kind of device: the protocol, connection settings and the list of tags. Many devices can share one profile. | | **Device type** | What a device is (PLC, CNC machine, filler and so on). You choose it; it sets the icon and how the Operations Center shows the device. | | **Discovery** (server discovery) | Searching the network for OPC UA servers or MTConnect agents. | ## E | Term | Meaning | | --- | --- | | **Edge gateway** | The Proxus software that runs near the machines, on a computer you choose (an industrial PC, a server or a virtual machine; x86 or ARM, Linux). It is not a hardware box. It reads the machines, runs functions and pipelines, keeps the data while the hub cannot be reached and forwards it. The hub runs one itself, called **SYSTEM**. | | **Effect** | Something a pipeline does outside itself: opening an alarm, sending a notification, writing to a device, calling an API. | | **Enterprise** | The top level of the plant hierarchy: the company. | | **Equipment** (equipment module) | The fifth level of the plant hierarchy, below **Line / cell**: one machine or unit. | ## F | Term | Meaning | | --- | --- | | **Function** | C# code that runs on edge gateways and works on live data. See [Functions SDK](https://proxus.io/docs/develop/functions-sdk). | ## G | Term | Meaning | | --- | --- | | **Good** (quality) | A value read without error, which can be trusted. | ## H | Term | Meaning | | --- | --- | | **Historian** | The Proxus store of all tag values over time, used by trends, reports and the Telemetry API. | | **Hub** | The central Proxus server: the screens, the configuration, the historian and the APIs. | ## L | Term | Meaning | | --- | --- | | **Line / cell** (process cell) | The fourth level of the plant hierarchy, below **Area**: a production line or cell. | ## M | Term | Meaning | | --- | --- | | **MasterToken** | The secret user name that MQTT clients use to read the UNS topics on a gateway's broker. | ## N | Term | Meaning | | --- | --- | | **Notification channel** | A way Proxus sends messages to people: email, SMS, Teams, Slack and others. See [Notification channels](https://proxus.io/docs/reference/notification-channels). | ## O | Term | Meaning | | --- | --- | | **On Change** | Sending only the values that changed since the last reading. Compare **Pass Through**. | | **Operational Graph** | A map of how devices, profiles, gateways, pipelines, rules, targets and dashboards depend on each other. | | **Operations Center** | The screen that shows the state of the plant's devices at a glance. | | **Outbound target** | A system outside Proxus that receives device values: a database, a message broker, a cloud service, a REST API. See [Outbound targets](https://proxus.io/docs/reference/outbound-targets). | ## P | Term | Meaning | | --- | --- | | **Pass Through** | Sending every reading with all its values. Compare **On Change**. | | **Pipeline** | A chain of nodes that changes data before it is stored (**Transport Pipeline**) or reacts to stored data (**Automation**). See [Pipeline nodes](https://proxus.io/docs/reference/pipeline-nodes). | | **Pipelines Only** | A target that receives data only from pipelines that name it, not from normal device delivery. | | **Platform CA** (Proxus Platform CA) | The certificate authority the hub creates on its first start. It issues the certificates of the hub's HTTPS (on new installations), its message server and every gateway. Install it as trusted on browsers and devices with **Download CA**, or replace it with your own through **Use Corporate CA**. | ## Q | Term | Meaning | | --- | --- | | **Quality** | How far a value can be trusted: **Good**, **Bad** or **Uncertain**. | | **Quarantine** | Data that a pipeline set aside for inspection instead of storing it normally. | ## R | Term | Meaning | | --- | --- | | **Read every** | How often all tags of a device are read. | | **Rule** | A condition on live values (for example "temperature above 80") with actions that run when it is met. See [Rules](https://proxus.io/docs/automate/rules). | ## S | Term | Meaning | | --- | --- | | **Shadow** (pipeline) | A pipeline published to run on real data without effects: what it would do is recorded in **Trace**, nothing is sent or written. | | **Site** | The second level of the plant hierarchy, below **Enterprise**: a plant or location. | | **Sleep mode** | The state of a device that stopped answering. The gateway tries again at growing intervals instead of every read cycle. | | **Sparkplug B** | An MQTT standard for industrial data. Proxus can publish the UNS in this format and send to Sparkplug B brokers. | | **SYSTEM** | The edge gateway that runs inside the hub. It reads machines on the hub's own network. | | **SYSTEM INTERNAL DB** | The outbound target that stands for the Proxus historian itself. | ## T | Term | Meaning | | --- | --- | | **Tag** | One value read from a device: a speed, a temperature, a counter, a state. | | **Token** (device) | A secret code of each device, used when the device sends its own values over MQTT or HTTP. | | **Trace** | The tab of a pipeline that shows samples of data passing through it and what it did or would do. | | **Transport strategy** | How a target receives values: **Pass Through**, **On Change** or **Pipelines Only**. | | **Trend Workspace** | The screen for plotting tag values over time and comparing them. | | **Trusted Server Certificate** | The CA or server certificate from the Certificate Store that an outbound target or an OPC UA device profile uses to check the server it connects to. | ## U | Term | Meaning | | --- | --- | | **Uncertain** (quality) | A value that was read but may be wrong, for example one the device marked as estimated or stale. | | **Unified Namespace (UNS)** | One tree of all plant data, ordered enterprise, site, area, line, equipment, device, tag. Proxus publishes it on MQTT and shows it in the **UNS Explorer**. See [Unified Namespace](https://proxus.io/docs/concepts/unified-namespace). | --- # Troubleshoot > How to find the cause of a problem in Proxus. Where the product reports errors, how to read them, and which page covers each area. Source: https://proxus.io/docs/troubleshoot Most problems in Proxus show up in one of a few places, and the message there usually names the cause. Start with the screen closest to the symptom, then follow the data back towards the machine. ## Follow the data 1. **Is the gateway connected?** In **Edge Gateways**, the status says `Online (for ...)`. If not, nothing behind it can work. See [Gateways](https://proxus.io/docs/troubleshoot/gateways). 2. **Is the device reading?** The device's status and each tag's value say whether the gateway reaches the device and reads each address. See [Devices](https://proxus.io/docs/troubleshoot/devices). 3. **Does the data arrive where you expect it?** Trends, the UNS and outbound targets each have their own conditions. See [Data](https://proxus.io/docs/troubleshoot/data). 4. **Does the automation run?** Pipelines, rules and functions report their deployment and errors. See [Automation](https://proxus.io/docs/troubleshoot/automation). ## Where Proxus reports problems | Place | What it shows | | --- | --- | | **Health Checks** | A list of findings across the system: offline gateways, devices that stopped sending, pipelines that run nowhere, objects the edge rejected. Start here when you do not know where to look. See [Health checks](https://proxus.io/docs/organize/health-checks). | | Device page | The device's status, the last error with its code, and each tag's value and quality. See [The device page](https://proxus.io/docs/connect/devices/device-page). | | **Edge Gateways** | Whether each gateway is connected, since when, and why not. | | **System Logs** | Log entries of the hub and every gateway, by level and source. See [System logs](https://proxus.io/docs/administer/system-logs). | | **Check** on an outbound target | Whether its parameters are complete, its last success and failure, and a connection test. | | Pipeline **Deployments** and **Trace** tabs | Where a pipeline runs, its last error, and samples of the data it handled. | | **Logs** on a function | The function's own log lines and errors. | ## Error codes Device errors carry a code such as `COMM_TIMEOUT_001`, a scope (`Device`, `Tag` or `Unknown`) and a confidence (`High`, `Medium`, `Low`). The code names the kind of problem, the scope says whether the whole device or one tag is affected, and the confidence says how sure Proxus is about its reading of the driver's message. The codes are listed in [Devices](https://proxus.io/docs/troubleshoot/devices#error-codes). ## When you ask for help Collect a [support bundle](https://proxus.io/docs/administer/support-bundle). It contains the logs and settings support needs, with passwords removed. Send the bundle to your Proxus partner, or to Proxus support through the [contact form](/contact), with the time the problem started. --- # Troubleshoot devices > What the connection test results, device statuses, sleep mode, tag errors and error codes mean, and what to check for each. Source: https://proxus.io/docs/troubleshoot/devices This page explains the messages Proxus shows when it cannot read a device or a tag, and what to check for each. Read it from the top when a device does not connect; jump to [Tag errors](#tag-errors) when only some values are wrong. ## The connection test **Test the connection** in the device setup wizard runs on the gateway you picked, so it proves what the gateway can reach, not what your own computer can. It runs these steps in order and stops at the first failure: | Step | Shown when it passes | What it checks | | --- | --- | --- | | Network | `
: reachable from the gateway` | The gateway opens a TCP connection to the device. | | Session | `Protocol session opened` | The device accepts the protocol's session (for OPC UA, SNMP, MTConnect, Haas and Heidenhain this is the only step). | | Identity | `Device identity read` | Siemens S7 only: the CPU's order number, shown as `The device says it is <...>.` | | Test read | a value next to each tag | Each tag is read once (at most 64 tags). | When the network step fails, the test also says whether the address is on one of the gateway's own networks: `
is not on any of the gateway's networks (). The gateway needs a route to it, or the address is wrong. Behind NAT (for example a gateway in Docker) this can be normal.` ### Test results | Result | Meaning | What to check | | --- | --- | --- | | ` did not answer.` | The gateway is offline or too old to run the test. | That the gateway shows **Online** in **Edge Gateways**. See [Gateways](https://proxus.io/docs/troubleshoot/gateways). | | `The gateway cannot reach the device.` | No TCP connection: wrong address, wrong port, the device is off, or a firewall or VLAN is in between. The detail says `Failed to connect to :` or `Connection to : timed out after ms`. | The IP address and port. From the gateway's host, try to reach the device (`ping`, or a TCP test to the port). Firewall rules between the gateway's network and the device. | | `The device refused the session.` | The network is fine, but the device did not accept the protocol. | For Siemens: rack and slot, and that the CPU allows **PUT/GET communication from remote partner**. For others: the protocol settings (unit ID, station number, security mode), and that the device is not limited to one client already connected. | | `No answer in time.` | The device or gateway did not finish within the test time (10 seconds plus time for the test read). | A slow network, a busy device, or the wrong protocol variant for this device. | | `The connection settings are incomplete.` | For example `The device address (Host) is empty.` | Fill in the address. | | `This gateway cannot test this protocol yet; you can still save the device.` | The gateway has no test for this protocol. | Save the device and watch its status. | | `The test did not succeed.` | Any other error. The detail is the driver's message. | Read the detail; see [Error codes](#error-codes). | ### Test read errors | Message | Meaning | | --- | --- | | `The address is empty.` | A tag has no address. | | `Invalid address format for selected protocol:
` | The address does not fit the protocol's form, for example `40001` where Modbus expects `x=3;0`. | | `Data type cannot be test-read.` | That type is read in normal operation but not in the test. | | `No answer.` | The device did not return this value. | ## Device status The device list and the device page show one status per device: | Status | Meaning | What to check | | --- | --- | --- | | **Connected** | The gateway reads the device and values arrive. | | | **Warning** | Connected, but some tags fail. The status text counts the tags that are OK, Bad and Disabled. | The failing tags, see [Tag errors](#tag-errors). | | **Sleep Mode** | The device stopped answering, and the gateway now only tries it now and then. | See [Sleep mode](#sleep-mode). | | **Offline** | No fresh values. `Offline/Stale, Last telemetry: