gRPC Integration API
The Integration API (chargelink.integration.v1, version 1.8.0) is the stable automation interface of ChargeLink for your own automation clients; the NI VeriStand bench uses it too. It is served by chargelink integration serve as plaintext HTTP/2 gRPC on 127.0.0.1:50051.
Start the server
The kit has a charger\ and a vehicle\ folder; the CLI is charger\bin\chargelink.exe.
$CL = 'C:\Program Files\DEVlink\ChargeLink\<VERSION>\charger\bin\chargelink.exe'
$Data = "$env:ProgramData\DEVlink\ChargeLink\data"
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" `
integration serve --listen 127.0.0.1:50051 --state-root "$Data\runtime\integration"
Keep the window open; the process runs in the foreground and stops with Ctrl+C. --state-root defaults to <runtime-root>\integration. There is no Windows service wrapper; run the server from a dedicated shell, a scheduled task or your own supervisor. Bind only to loopback unless the network design in Production Security is in place.
Verify from the CLI
$EP = 'http://127.0.0.1:50051'
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json integration health --endpoint $EP
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json integration capabilities --endpoint $EP
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json integration session-smoke --endpoint $EP --protocol iso15118-2 --role evse
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json signals list --endpoint $EP
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json signals smoke --endpoint $EP
Expected: health_status: serving, api_version: 1.8.0, product ChargeLink Native; capabilities with 19 capability entries (each with enabled and a claim_boundary), the protocol list, max_page_size 1000, max_signal_batch_size 512 and 94 canonical signals. integration capabilities without --endpoint answers in embedded mode without a server.
The capability bound-live-protocol-observer: a session whose configuration_json carries a "listener" object is bound. StartSession then starts a charger listener for it and answers RUNNING only once the listener is ready; Session.listener, GetProtocolState and both event streams report the listener's state (requested, listener ready, peer connected, protocol running, protocol ended, protocol failed). Unknown keys in the listener object are refused, a bound listener reports only the first protocol session of its run, and a stand-alone listener started from the CLI stays unbound (GetProtocolState = unobserved). None of this establishes electrical state.
Access token
At every start the server writes a new 256-bit random token to <state-root>\api-token (readable by the owner and SYSTEM only) before it opens the port, and every call must carry it as authorization: Bearer <token>; a missing or wrong token is answered UNAUTHENTICATED. Every CLI command with --endpoint or --grpc-endpoint reads the file named by CHARGELINK_API_TOKEN_FILE, or <runtime-root>\integration\api-token when the variable is unset. On the NI VeriStand bench, the owner host handles the token itself. A third-party client reads the file itself and adds the header. The server accepts only a loopback --listen address; a non-loopback address is refused with exit 40 before any token is written.
$env:CHARGELINK_API_TOKEN_FILE = "$Data\runtime\integration\api-token" # only when the state root differs from the runtime root default
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json integration health --endpoint $EP
Read and write canonical signals
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json signals list --endpoint $EP --namespace Vehicle
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json signals read --endpoint $EP --signal Vehicle.SocPct --signal Charger.PresentVoltageV --signal Protocol.SessionState
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json signals write --endpoint $EP --signal Vehicle.SocPct=35 --signal Vehicle.TargetVoltageV=800
Signals are written as ID=VALUE; only bidirectional signals accept writes. The full dictionary with units and directions is on the VeriStand Signal Mapping page.
Built-in smokes
| Command | Exercises | Output |
|---|---|---|
integration session-smoke | Create, start, stop, delete a session record | session ID and states |
integration full-smoke --evidence-source DIR | The baseline services with a supplied evidence directory or manifest | report |
integration sil-smoke [--ipv6-host ::1 --interface-index 0] | Deterministic time, both managed SIL roles over real IPv6 loopback networking, TLS/EXI, campaign bridge | .chargelink\integration\sil-smoke (or --output) |
integration hil-smoke | Vendor-neutral HIL adapter SDK with the deterministic hardware simulator: lifecycle, mapping, calibration, sync, faults, interlocks, emergency stop, evidence | hil-smoke directory |
integration xil-smoke | ASAM XIL bridge reference (Framework, MAPort, EESPort) with the deterministic reference provider | xil-smoke directory |
integration factory-smoke | Factory/EOL station, recipe, measurement, disposition, label and evidence | factory-smoke directory |
integration enterprise-smoke | Editions, RBAC, service identities, sealed secrets, audit chain, fleet, signed updates, rollback (reference implementation) | enterprise-smoke directory |
integration compatibility | API compatibility of the installed release | report |
Each smoke writes a report whose claim_boundary states what it proves. The SIL smoke is the closest thing to a full two-role protocol session without hardware; the HIL, XIL, factory and enterprise smokes exercise the service workflows with reference implementations, not physical equipment.
Services
14 services: HealthService, ConfigurationService, SessionService, ProtocolService, SignalService, TimeService, SilService, HilService, XilService, TestCampaignService, EvidenceService, ReportService, FactoryService and EnterpriseService. Every request carries a RequestContext (request_id, correlation_id, session_id, campaign_id, requested_api, idempotency_key) and every response a ResponseContext. The RPC list is in the Integration API Reference.
Write your own client
- Obtain
integration.proto(packagechargelink.integration.v1) for the installed release from your ChargeLink delivery or from theschemas/docsdirectory of the package. - Generate a client with your language's gRPC tooling (protoc, grpcio-tools, grpc-dotnet, and so on).
- Call
HealthService.GetHealthandGetCapabilitiesfirst and compareapi_versionwith the version you generated against. Minor versions are additive. This manual documents API version 1.8.0. On the NI VeriStand bench, use the owner host andchargelink.exefrom the same release; components of different releases refuse each other. - Use the CLI smokes as reference behaviour: if
session-smokepasses and your client fails, the difference is in the client.
Security boundary
The management API is local only: loopback addresses, a per-start bearer token, no TLS transport. The token protects the API from other local accounts and from processes that cannot read the state root; it does not protect against the account that runs ChargeLink or an administrator. Remote access is not offered; do not expose the port through a proxy or tunnel. EnterpriseService.EvaluateAuthorization exists as an RPC but is not enforced on other calls.
Troubleshooting
| Symptom | Check | Action |
|---|---|---|
integration health fails | Get-Process chargelink; Test-NetConnection 127.0.0.1 -Port 50051; netstat -ano | findstr :50051 | Start the server; fix the endpoint or the port owner |
| Health passes, your client fails | session-smoke, signals smoke | Compare request shapes and API version; capture the client's error |
GetProtocolState is unobserved | the session carries no "listener" object | Expected for a CLI-started or unbound listener; bind the session or read the listener's artifacts |
CL-RUNTIME-001, "does not have valid authentication credentials" | token file missing, unreadable or stale | Point CHARGELINK_API_TOKEN_FILE at the running server's <state-root>\api-token; the file changes at every server start |
| State lost after restart | --state-root | Use the same state root on every start |

