Skip to content

About

HSL Gateway is a gRPC service designed to bridge industrial devices. It leverages the HslCommunication library to poll devices efficiently and exposes real-time data via a gRPC interface.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

40 Commits

Folders and files

Repository files navigation

HSL Gateway

HSL Gateway is a high-performance, production-ready gRPC service designed to bridge industrial devices (Siemens, Mitsubishi, Omron, Allen-Bradley, Modbus and 15 more vendors) with modern IT systems. Built on .NET 10 LTS, it leverages the HslCommunication library to poll devices efficiently and exposes real-time data via a gRPC interface.

πŸš€ Features

  • Multi-Protocol Support: 75 device types across 20 vendors β€” Siemens S7/PPI/MPI/Fetch-Write, Modbus TCP/RTU/ASCII/UDP, Mitsubishi MELSEC, Omron, Allen-Bradley, Panasonic, Keyence, Delta, Fatek, Fuji, Inovance, XINJE, LSIS, Beckhoff, GE, Yokogawa, YASKAWA, Toyota, Vigor and MegMeet, over Ethernet or serial. See docs/DeviceTypes.md.
  • gRPC Interface: Fast, strongly-typed API for reading tag values and device lists, with server reflection enabled.
  • High Performance: In-memory caching (TagValueCache) ensures low-latency data access.
  • Background Polling: Dedicated background service (PollingWorker) handles device communication independently of API requests.
  • Resilient: Automatic reconnection and error handling for device communication.
  • Docker Ready: Includes a multi-stage Dockerfile for easy deployment on Linux/Kubernetes.
  • Simulator Included: Comes with a Modbus TCP simulator for testing and verification.
  • Scalable: Supports connecting to multiple devices simultaneously with parallel polling.
  • Enterprise Ready: Boots with HslCommunication enterprise licenses supplied via environment variables or certificate files.

πŸ› οΈ Technology Stack

  • Framework: .NET 10 LTS (ASP.NET Core)
  • Communication: gRPC (HTTP/2)
  • Driver Library: HslCommunication (NuGet)
  • Architecture: Clean Architecture with Dependency Injection

πŸ“¦ Getting Started

Prerequisites

  • .NET 10 SDK β€” the exact version is pinned in global.json
  • Docker (optional, for containerized deployment)

If you use proto, .prototools already pins the SDK:

proto install

Installation

git clone https://github.com/yourusername/HSL-gateway.git
cd HSL-gateway
dotnet restore

Running Locally

Start the simulator (optional, for testing) β€” it serves three Modbus TCP devices on ports 50502-50504:

dotnet run --project HslSimulator/HslSimulator.csproj

Then start the gateway, which listens on port 50051:

dotnet run --project HslGateway/HslGateway.csproj

To run against the simulator with devices and tags already configured, use one of the bundled environments:

ASPNETCORE_ENVIRONMENT=MultiDevice dotnet run --project HslGateway/HslGateway.csproj

Testing

dotnet test HslGateway.sln

HslVerifier is an end-to-end smoke test that exercises read, write, streaming, and dynamic reconfiguration against a running gateway, and exits non-zero on failure:

HSL_GATEWAY_ADDRESS=http://localhost:50051 dotnet run --project HslVerifier

βš™οΈ Configuration

Configure devices and tags in appsettings.json, or manage them dynamically through the ConfigManager gRPC service.

The persisted file wins. The gateway seeds from appsettings.json only on first boot, then writes every change to data/gateway-config.json and prefers that file from then on. If edits to appsettings.json appear to be ignored, delete the persisted file. Its location is set by GatewayPersistence:ConfigFilePath, and the listening port by Gateway:GrpcPort.

"Gateway": {
  "Devices": [
    {
      "Id": "siemens_01",
      "Type": "SiemensS7",
      "Ip": "192.168.1.10",
      "Port": 102,
      "Rack": 0,
      "Slot": 1,
      "PollIntervalMs": 1000
    },
    {
      "Id": "modbus_01",
      "Type": "ModbusTcp",
      "Ip": "127.0.0.1",
      "Port": 50502,
      "PollIntervalMs": 2000
    }
  ],
  "Tags": [
    {
      "DeviceId": "siemens_01",
      "Name": "motor_speed",
      "Address": "DB1.0",
      "DataType": "double"
    },
    {
      "DeviceId": "modbus_01",
      "Name": "line_power",
      "Address": "40001",
      "DataType": "short"
    }
  ]
}

Type names the device family. docs/DeviceTypes.md lists all 75 supported values with their vendor, transport and default port; matching is case-insensitive. PlcModel selects the vendor series where one applies β€” Siemens (S200, S200Smart, S300, S400, S1200, S1500; defaults to S1500), Inovance, XINJE, Delta, Omron and LSIS β€” and Rack/Slot apply to Siemens and the CIP drivers. Station carries the unit id β€” omit it to accept the protocol's own default, which is not always 1.

Serial types use the serial fields instead of Ip/Port:

{
  "Id": "rtu_01",
  "Type": "ModbusRtu",
  "PortName": "/dev/ttyUSB0",
  "BaudRate": 9600,
  "DataBits": 8,
  "StopBits": 1,
  "Parity": 0,
  "Station": 1,
  "PollIntervalMs": 1000
}

DataType accepts bool, short, int, long, float, and double (the default).

Multi-Device Support

The Gateway supports connecting to multiple devices simultaneously. Simply add more entries to the Devices array in appsettings.json.

  • Each device runs in its own independent polling loop.
  • A slow or disconnected device will not affect the performance of other devices.
  • You can mix different protocols and vendors (e.g., a Siemens PLC, a MELSEC PLC and a serial Modbus device) in the same configuration.

Authentication

The gRPC surface can reconfigure devices and write to PLCs, so it should not be reachable by an unauthenticated caller. Set an API key to require one on every call:

Security__ApiKey=$(openssl rand -hex 32) dotnet run --project HslGateway/HslGateway.csproj
"Security": {
  "ApiKey": "",
  "RequireApiKey": false,
  "HeaderName": "x-api-key"
}

Clients send it as x-api-key: <key> or authorization: Bearer <key>; calls without a valid key fail with UNAUTHENTICATED. / and /health stay open so orchestrator probes work.

When ApiKey is empty the gRPC surface is unauthenticated, and the gateway logs a warning saying so at every startup. That is the default so existing deployments and the simulator scripts keep working β€” set RequireApiKey: true in production to make an unauthenticated instance fail to start instead.

Supply the key through the environment rather than committing it to appsettings.json. There is no TLS, so put the gateway behind a trusted network or a TLS-terminating proxy; the key alone does not protect the traffic.

Enterprise License Bootstrap

Set EnterpriseLicense in HslGateway/appsettings.json (or the environment-specific file) to enable automatic activation of HslCommunication enterprise features at startup:

"EnterpriseLicense": {
  "AutoLoadOnStartup": true,
  "CertificateFilePath": "data/hsl-enterprise.cert",
  "CertificateBase64EnvironmentVariable": "HSL_ENTERPRISE_CERT_BASE64",
  "AuthorizationCodeEnvironmentVariable": "HSL_ENTERPRISE_AUTH_CODE",
  "ContactInfo": "ops-team@example.com"
}

On boot the gateway applies the first available artifact in this order:

  1. HSL_ENTERPRISE_CERT_BASE64 (Base64 string that represents the official HslCommunication certificate file).
  2. HSL_ENTERPRISE_AUTH_CODE (plain-text authorization code provided by HslCommunication).
  3. The file path defined by CertificateFilePath (default data/hsl-enterprise.cert).

If both AutoLoadOnStartup is true and one of the above values exists, EnterpriseLicenseStartupService logs the successful activation and moves on with the normal startup flow. Activation is never fatal: without a license the gateway still starts in community mode. Clear or disable AutoLoadOnStartup to skip the attempt entirely.

A license can also be applied to a running gateway through ConfigManager/ActivateEnterprise, which optionally persists the certificate to CertificateFilePath.

πŸ”Œ API Usage (gRPC)

You can use any gRPC client (C#, Python, Go, Node.js, etc.) or tools like grpcurl. Server reflection is enabled, so no local copy of gateway.proto is needed:

grpcurl -plaintext localhost:50051 list

Unknown devices and tags fail with NOT_FOUND; a configured tag that has not been polled yet returns quality unknown.

Get Tag Value:

grpcurl -plaintext -d '{"deviceId": "modbus_01", "tagName": "line_power"}' localhost:50051 hslgateway.Gateway/GetTagValue

List Devices:

grpcurl -plaintext localhost:50051 hslgateway.Gateway/ListDevices

Write Tag Value:

grpcurl -plaintext -d '{"deviceId": "modbus_01", "tagName": "line_power", "value": 50}' localhost:50051 hslgateway.Gateway/WriteTagValue

Subscribe to Tag Value (Streaming):

grpcurl -plaintext -d '{"deviceId": "modbus_01", "tagName": "line_power"}' localhost:50051 hslgateway.Gateway/SubscribeTagValue

πŸ§ͺ Test Scripts

Interactive bash scripts live under scripts/tests and spin up every component you need for manual verification:

  • scripts/tests/multi-device.sh: launches three Modbus simulators, the gateway (using the MultiDevice environment), and the multi-device test client (foreground in your terminal) so you can validate polling/subscription across devices. Pass --auto (or set HSL_TEST_AUTO=1) if you need it to run a fully automated demo scenario.
  • scripts/tests/subscription.sh: launches a single simulator, the gateway (using the Subscription environment), and the subscriber client with a guided flow that mirrors the subscription demo and write tests.

Run them from the repo root using Git Bash, WSL, Linux, or macOS bash. Each script builds the required projects, deletes its environment's persisted config so the scenario is reproducible, starts every process in the same terminal session, and cleans up automatically when you press Ctrl+C.

🐳 Docker Deployment

Build and run the container:

docker build -t hsl-gateway .
docker run -p 50051:50051 -v hsl-data:/app/data hsl-gateway

The image runs as a non-root user. Mount a volume at /app/data to keep the live configuration and any persisted certificate across restarts.

πŸ“„ License

The source code in this repository is licensed under the MIT License β€” see LICENSE.

This does not extend to HslCommunication. That package is proprietary software owned by ζ­ε·žθƒ‘ε·₯η‰©θ”η§‘ζŠ€ζœ‰ι™ε…¬εΈ, distributed under the vendor's own terms, and it supplies every device driver here β€” the gateway cannot run without it. Review those terms before deploying, particularly for commercial use or redistribution, and note that enterprise features require a license purchased from the vendor. See THIRD-PARTY-NOTICES.md for the full dependency breakdown.

About

HSL Gateway is a gRPC service designed to bridge industrial devices. It leverages the HslCommunication library to poll devices efficiently and exposes real-time data via a gRPC interface.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages