Printer: Installation & Getting Started

Guide for installing the Printer and getting started with API.

Printer Technical Guide

This document describes how to use the software components of the Bergstein DIGI Gen3 Printer.

DIGI HMI

The main interface of the printer is the DIGI HMI app. This app manages and directs printer process commands for the printer. Like reading a Job file, addressing print hardware and providing data to the Controller/PLC.

The app runs in Windows under the standard location: "C:/DigiHMI" (app folder). Application data, like machine variables and recipes, are stored separately at the standard location: "C:\ProgramData\Bergstein Digital BV\Bergstein DIGI Manager" (data folder). Application settings are loaded through an 'appsettings' file at standard location: "C:/DigiHMI/appsettings.json".

Under all circumstances should the HMI app be running for the printer to function. The DIGI HMI app must have read and write access to both app & data folders.

Requirements

The operating system must be Windows 11 or higher. The system specification shall be: Recommended:

Also the following software packages must be installed:

Settings

Various app settings are encapsulated in the 'appsettings.json' file. If you want to change it, its advised to have knowledge about .JSON files (e.g. see https://en.wikipedia.org/wiki/JSON). Before changing its recommended to make a copy of this file so it can be restored when something goes wrong.

What follows is a breakdown of the most common options in this settings file;

KeyDefaultComment
JobHandlerOptions__NumberOfSides0If the printer has a jig capable of printer multiple sides, else value is 0
JobHandlerOptions__NumberOfActuatorPositionsPerSide0If the printer has a jig with at least one actuator, else value is 0
FeatureFlags__PrinterControllerApiEnabledtrueIf true, exposes the HTTP API
FeatureFlags__DeveloperModefalseIf true, exposes the HTTP API developer page at '/swagger'
FeatureFlags__DetailedLoggingtrueIf true, logs debug level messages
FeatureFlags__HTTPStrueIf true, enforces HTTPS on the API (e.g. HTTP2 with TLS1.3)
FeatureFlags__SimulatedControllerfalseIf true, mocks the API with a simulated controller behavior
FeatureFlags__SimulatedControllerRandomBehaviorfalseIf true, and the SimulatedController is true, the bahavior is randomized (random stops, errors and messages)
FeatureFlags__SimulatedControllerControllerModefalseDeprecated
FeatureFlags__SimulatedControllerWorkerModefalseDeprecated
FeatureFlags__AllowRemoteStartfalseIf true, allows the 'Start' API command to take effect; start JobQueue processing
FeatureFlags__AllowRemoteStopfalseIf true, allows the 'Stop' API command to take effect; stop JobQueue processing
FeatureFlags__WorkerModeEnabledfalseDeprecated
ServerOptions__AllowedOrigins["*"]A list of origin URL strings. Sets the HTTP allow-origin whitelist. A "*" indicates a wild card and allows all API client origins
ServerOptions__HttpsRedirectionPort6001The HTTPS port which non-HTTPS traffic is redirected to if 'ServerOptions__RedirectToHttps' is set to 'true'
ServerOptions__MaximumNumberOfGrpcStreamingClients5The maximum number of unique(concurrent) client connection that can start a gRPC server stream subscription.
Kestrel__Endpoints__Https1__Url"https://*:6001"The address/URL of the HTTPS endpoint.
Kestrel__Certificates__Default__Path"C:\Temp\ssl\certificate.pfx"The path to the '.pfx' file of the X509 certificate to use for the HTTP API
Kestrel__Certificates__Default__Password""The password of the X509 certificate

API

External integration can be achieved by using its HTTP API, which comes in two forms; gRPC & JSON REST. The API is exposed as HTTPS on port 6001 using TLS1.3 . A self signed X509 certificates is used when the printer is delivered. For optimal security its advised to provide your own certificate instead of the supplied self-signed-certificate.

The capabilities of the API are described in comments in the IDL (Interface-Definition-Language) of the API. For gRPC this is the corresponding protobuf file: https://developer.bergstein.com/api/printer-gen3/v1.4.0/grpc/bergstein.digi.printer.proto . For JSON REST this is the corresponding OpenAPI file: https://developer.bergstein.com/api/printer-gen3/v1.4.0/rest/bergstein.digi.printer.json .

The gRPC API is our native interface, the JSON REST API is transcoded from that API and lacks the capability to transcode server streams. So please consult the following table in your decision of API to use;

EndpointCommentgRPCREST
PrinterControllerService.StartStarts the printer
PrinterControllerService.Stop
PrinterControllerService.SendPrintJobSends a DJOB print file to the printer
PrintControllerService.GetPrintJobStatusGets the state of the current active job
PrinterControllerService.GetPrinterStateGets the state of the printer
PrinterControllerService.GetNotificationsGets all the notifications of the printer
PrinterControllerService.OnJobStatusUpdatedSubscribe on server stream to be notified when a Job changes state
PrinterControllerService.OnNotificationSubscribe on server stream to be notified when a new notification is made
PrinterControllerService.OnPrinterStatusUpdatedSubscribes on server stream to be notified when the printer changes state
PrinterControllerService.OnRequestJobSubscribes on server stream to be notified when the printer request new job
RecipeService.CreateRecipeCreates a new recipe in the printer
RecipeService.GetRecipeGet a specified recipe stored in the printer
RecipeService.ListRecipeList all stored recipes in the printer
RecipeService.UpdateRecipeUpdates a specified recipe in the printer
RecipeService.DeleteRecipeDeletes a specific recipe in the printer
VariableService.GetVariableGets a variable, which is a Key-Value pair part of the Recipe, from the printer
VariableService.ListVariableGets a variable, which is a Key-Value pair part of the Recipe, from the printer

Use cases

Using the API means sending an specific HTTP commands by messaging an endpoint and receiving a corresponding reply.

If you wish to issue these HTTP commands from the network, you should enable inbound TCP traffic for that API port (e.g. 6001) on the host device and along the network.

Example 1 - Getting Printer State

For example we want to get the current state of the printer using REST:

JSON REST - HTTP GET on 'https://:6001/printer_controller/v1/printer_controller/printer_state'.

Then you will get a reply like:

{
  "status": "PrinterStatus_Started"
}

Example 2 - Getting all error notifications

For example we want to get all the error notifications in the printer using REST:

JSON REST - HTTP GET on 'https://:6001/printer_controller/v1/printer_controller/notifications'.

Then you will get a reply like:

{
  "notifications": [
    {
      "id": "8233849b-c813-404e-bfe7-b8ab0aafe03b",
      "type": "NotificationType_Error",
      "startTime": "2026-09-04T06:44:34.530949400Z",
      "componentName": "Shift shuttle",
      "content": "Shift shuttle not in position"
    },
    {
      "id": "03561b5f-df76-4ac1-8ab3-dbea031a0d61",
      "type": "NotificationType_Warning",
      "startTime": "2026-09-04T06:44:35.315939800Z",
      "componentName": "Shuttle B",
      "content": "General motion warning of shuttle"
    },
    {
      "id": "01174e4f-f039-4002-843d-48ca6b101e96",
      "type": "NotificationType_Warning",
      "startTime": "2026-09-04T07:43:09.012756300Z",
      "componentName": "Job Queue",
      "content": "Unable to print layer 'Spot4' no available hardware found"
    },
    {
      "id": "3c6f5024-abe7-4d03-9fa9-780447426db2",
      "type": "NotificationType_Warning",
      "startTime": "2026-09-04T08:21:03.757707700Z",
      "componentName": "Lift",
      "content": "Not In Print Position"
    },
    {
      "id": "1165a0b9-b92f-4c8c-a55a-4bba2b4b65ac",
      "type": "NotificationType_Info",
      "startTime": "2026-09-04T08:22:03.107905700Z",
      "componentName": "Printer PLC interface",
      "content": "Drip tray attached"
    },
    {
      "id": "ee917c74-de79-48b9-900e-29bbc23a7800",
      "type": "NotificationType_Info",
      "startTime": "2026-09-04T08:22:03.115199400Z",
      "componentName": "Printer PLC interface",
      "content": "Drip tray 1 attached"
    },
    {
      "id": "70e76063-9e14-49bc-a742-53be3448db87",
      "type": "NotificationType_Info",
      "startTime": "2026-09-04T08:22:03.140225200Z",
      "componentName": "Printer PLC interface",
      "content": "Auto fire running"
    },
    {
      "id": "6186e91a-6297-4a46-b2a9-5ff71f732414",
      "type": "NotificationType_Error",
      "startTime": "2026-09-07T12:00:16.347070500Z",
      "componentName": "Printer PLC interface",
      "content": "No active print job"
    }
  ]
}

Next you can select the messages which have the "type" of value "NotificationType_Error".

Example 3 - Get the current Job state

For example we want to get the current Job state from the printer:

REST - HTTP GET on 'https://:6001/printer_controller/v1/printer_controller/job_state'.

Then you will get a reply like:

{
  "jobId": "00000861-0000-0000-0000-000000000000",
  "jobName": "Job7x15_360L5",
  "status": "JobStatus_Printing"
}

If you fetch this state when the current job is just about done you might get:

{
  "jobId": "00000861-0000-0000-0000-000000000000",
  "jobName": "Job7x15_360L5",
  "status": "JobStatus_Finished"
}

Example 4 - Streaming Job state

For example we want to get immediate notice of the current Job changing state from the printer:

gRPC - HTTP printer.PrinterControllerService.OnJobStatusUpdated

You will get a streamed reply like at '14:00:00':

{
  "jobId": "00000861-0000-0000-0000-000000000000",
  "jobName": "Job7x15_360L5",
  "status": "JobStatus_Idle"
}

Then a few moment later the printer is started and you could receive this at '14:00:30':

{
  "jobId": "00000861-0000-0000-0000-000000000000",
  "jobName": "Job7x15_360L5",
  "status": "JobStatus_Active"
}

Next a the printer has loaded and initialized everything and starts printing at '14:00:35':

{
  "jobId": "00000861-0000-0000-0000-000000000000",
  "jobName": "Job7x15_360L5",
  "status": "JobStatus_Printing"
}

Finally a the following response could be returned when the printer finishes the job at '14:01:00':

{
  "jobId": "00000861-0000-0000-0000-000000000000",
  "jobName": "Job7x15_360L5",
  "status": "JobStatus_Finished"
}

Back to documents