Skip to content

Local Adapter Development Setup

The canonical, published version of this guide lives on pq-web at howto/enable-dev.html.

This guide explains how to run and debug your adapter from Visual Studio / Rider against an installed PQ box, instead of running it as a container inside the deployment.

Prerequisites

  • An installed PQ deployment you can administer (or an administrator who can change it for you)
  • Your adapter project in Visual Studio / Rider
  • Your development machine can reach the PQ box over the network

The Problem

A PQ deployment keeps its internal services private:

  • NATS (port 4222) — messaging between adapters and server
  • Internal API (/Internal/*) — adapters fetch authorizations, device config, etc.

This is intentional for production security. Adapters deployed with the box reach these over the deployment's internal network. Your adapter runs outside it, so the box must be switched to development mode.

Step 1: Switch the box to development mode

Development mode starts two services on the box:

  • nats-dev publishes NATS on port 4222.
  • dev-gateway opens the Internal API (/Internal/*), the camera streaming API (/go2rtc/) and the identity server admin console (/idp/admin/) on the box's HTTPS front door. Outside development mode the front door answers these paths with HTTP 404.

The administrator of the box enables it with one command, run on the box:

docker compose -f /opt/pq/compose/docker-compose.yml --profile dev up -d nats-dev dev-gateway

/opt/pq/compose/ is where the Linux installer places the deployment's docker-compose.yml. On another platform, use the path of the docker-compose.yml in the installation directory.

To switch development mode off:

docker compose -f /opt/pq/compose/docker-compose.yml --profile dev stop nats-dev dev-gateway

Development mode does not survive a redeploy of the box — after a redeploy, run the first command again.

Once enabled, port 4222 is reachable from anywhere on the LAN for anyone who has the deployment's NATS credentials, and the opened front-door paths are reachable for anyone who can reach the box. Enable it only on a development box.

Step 2: Internal API — normally nothing to do

In development mode your adapter reaches /Internal/* through the box's HTTPS front door, using the base URL and X-Api-Key it receives automatically at registration. The adapter's HTTP client skips TLS validation, so there is no CA setup either. If /Internal/* returns HTTP 404, development mode is off: run Step 1.

Only as a fallback — if /Internal/* returns HTTP 403 — does an administrator set InternalApi__AllowExternal=true on the server service and restart it.

Step 3: Configure Your Adapter

Write the NATS connection into ~/.pq/adapter-dev.json:

{
  "Mq": { "Host": "<box-address>:4222", "User": "<nats-user>", "Password": "<nats-password>" }
}

Use localhost:4222 when your adapter runs on the box itself.

The framework reads this file as a fallback for any locally-run adapter that has no complete Mq configuration from a stronger source, so you configure NATS once instead of per adapter. To override it for a single adapter, put the same Mq section in that adapter's appsettings.Development.json.

Take the user and password from the deployment's configuration, or from its administrator.

The server API URL is provided during adapter registration, so you do not configure it manually.

Adapter logs in Grafana

Set OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 as a persistent user environment variable. The telemetry collector runs all the time, so nothing has to be turned on for it. Adapter logs then appear in Grafana at https://<box-address>/grafana/d/pq-home.

The collector listens on the box's loopback interface only, so this works when your adapter runs on the box itself.

Step 4: Run Your Adapter

Start your adapter from Visual Studio / Rider. It will:

  1. Connect to NATS on port 4222
  2. Register with the server
  3. Receive the API base URL in the registration response
  4. Call /Internal/Adapter/* endpoints for device config, authorizations, etc.

Stopping Development Mode

When you finish, have the administrator turn development mode off. The box then stops publishing NATS and serves adapters over its internal network again.

Security Notes

  • Never enable development mode in production — it publishes NATS on 0.0.0.0 with the deployment's own credentials
  • InternalApi__AllowExternal=true bypasses IP-based protection on /Internal/* endpoints — never leave it set outside of active troubleshooting
  • In production, adapters run inside the deployment and reach services over its internal network

Troubleshooting

NATS Connection Refused

Error: Connection refused to <box-address>:4222

Development mode is off, or a redeploy reverted it. Ask the administrator to enable it again, then check that port 4222 answers on the box.

403 Forbidden on /Internal/* Endpoints

HTTP 403 Forbidden when calling /Internal/Adapter/...

Ask the administrator to set InternalApi__AllowExternal=true on the server service and restart it.

Adapter Not Receiving Commands

  1. Check the NATS connection in adapter logs
  2. Verify the adapter registered successfully (look for AdapterConfigurationResponse in logs)
  3. Check that the device is started in PQ UI

Architecture Overview

┌─────────────────────────────────────────────────────────┐
│  PQ box                                                 │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐                  │
│  │   DB    │  │  NATS   │  │ Server  │                  │
│  └─────────┘  └────┬────┘  └────┬────┘                  │
│                    │            │                       │
│         internal network        │                       │
│                    │            │                       │
│              port 4222     HTTPS front door             │
└────────────────────┼────────────┼───────────────────────┘
                     │            │
              ┌──────┴────────────┴─────────────────────┐
              │      Your Development Machine           │
              │  ┌───────────────────────────────────┐  │
              │  │  Your Adapter (Visual Studio)     │  │
              │  │  - Connects to NATS on :4222      │  │
              │  │  - Calls /Internal/* over HTTPS   │  │
              │  └───────────────────────────────────┘  │
              └─────────────────────────────────────────┘

Next step

When the adapter runs from your IDE, build its image and test it on the device with the lab rig. The lab uses the same development mode.