Heidenhain DNC

The Connectware Heidenhain DNC protocol implementation makes it possible to interact with CNC machines via the Heidenhain DNC communication protocol. It offers the possibility to read data and status information, to manipulate the tool and pocket table, and to access data as well as files on the filesystem. A machine connection is defined by:

  • Connection settings (how to connect to the machine), and

  • Data mappings (how to map data from Heidenhain to MQTT)

Cybus Heidenhain Agent

In order to access the Heidenhain DNC COM component, the Connectware makes use of the Windows based Cybus Heidenhain Agent running as a Windows Service.

-----------         ---------           ---------------
| Machine | <-----> | Agent | <-------> | Connectware |
-----------   RPC   ---------   MQTTS   ---------------

The Cybus Heidenhain Agent is a Windows Service implementing the Heidenhain RemoTools SDK which provides a Microsoft COM component for communication with Heidenhain DNC interfaces. Use the convenient MSI Installer package for installation. After installation the agent needs to be enabled with the Windows Service application. Optional, but recommended is to set the restart behavior of the service to restart on failure. Agent log messages can be found in the Windows Events.

Commissioning file specifics

The following sections describe the configuration objects Cybus::Connection and Cybus::Endpoint. See also the example Heidenhain reference commissioning file

Connection Properties

agent (string, required)

The name of the agent connecting to the CNC machine. Must match the name that is being used at the heidenhain-agent.exe executable.

Example: "heidenhain-agent-1"

ipAddress (string)

IP Address or hostname of the CNC machine

Examples: "localhost", ""

cncType (string, enum)

Type of the CNC control

This element must be one of the following enum values:

  • tnc640

  • itnc530

  • tnc426

Default: "tnc640"

Examples: "tnc640", "itnc530", "tnc426"

domain (string)

Name of the edge communication domain

Default: "edge.cybus"

Example: "edge.cybus"

plcPassword (string)

Password to grant access to PLC functionality

Example: "807667"

tablePassword (string)

Password to grant access to TABLE functionality

Example: "807667"

usrPassword (string)

Password to grant access to USR functionality

Example: "807667"

sysPassword (string)

Password to grant access to SYS functionality

Example: "807667"

connectionStrategy (object)

If a connection attempt fails, retries will be performed with increasing delay (waiting time) in between. The following parameters control how these delays behave.

Properties of the connectionStrategy object:

initialDelay (integer)

Delay (waiting time) of the first connection retry (in milliseconds). For subsequent retries, the delay will be increased according to the parameter incrementFactor which has a default value of 2.

Default: 5000

Additional restrictions:

  • Minimum: 1000

maxDelay (integer)

Maximum delay (waiting time) to wait until the next retry (in milliseconds). The delay (waiting time) for any subsequent connection retry will not be larger than this value. Must be strictly greater than initialDelay.

Default: 30000

incrementFactor (integer)

The factor used to increment initialDelay up to maxDelay. For example if initialDelay is set to 1000 and maxDelay to 5000 the values for the delay would be 1000, 2000, 4000, 5000.

Default: 2

Additional restrictions:

  • Minimum: 2

Endpoint Properties

description (string)

Some descriptive text about the endpoint

method (string, required)

The function to call on the DNC control

Example: "isConnected"

params (array)

Only for subscribe: The parameter values for the function call to set up subscriptions. (For read calls, the function parameters are given in the payload data instead.)

The elements of the array must match at least one of the following properties:






The schema defines an array with all elements of the type string.




Examples: [1,"NAME"], ["this","that"]

pollInterval (integer)

Only for subscribe operation using type poll: Interval in milliseconds to poll the property

Default: 1000

Example: 1000

type (string, enum)

Only subscribe operation: Choose whether the subscription should be polled by the Connectware or whether it should be notified by DNC event notifiers.

This element must be one of the following enum values:

  • poll

  • notify

Example: "notify"

Data mappings

The data mappings are described in the Heidenhain Methods section below. Each data mapping of a Heidenhain method is described by

  • Communication pattern

  • Heidenhain method (e.g. setToolTableRow), see section below

Each Heidenhain method provides one of the following three possible access patterns:

  • subscription

  • read implementing a request/response pattern (or write as an alias)

  • notification pattern


The subscribe pattern offers the possibility to subscribe to a Heidenhain method. This polls the specified method in a given interval.

Example mapping:

 2  type: Cybus::Endpoint
 3  properties:
 4    protocol: Heidenhain
 5    connection: !ref heidenhainConnection
 6    topic: myCustomOutputTopic
 7    subscribe:
 8      type: poll
 9      method: getState
10      pollInterval: 5000

Payload format:

The MQTT message of the output data will be sent to the topic as specified in the endpoint configuration (in the example: myCustomOutputTopic), see also topic property.

The message has the following format:

{ "result": <data>, "timestamp": <timestamp> }


The read property of an endpoint implement a request/response pattern. This offers the possibility to request a machine action and receive a response. The pattern follows the JSON-RPC 2.0 Specification, with two exceptions: The method member is set by the Cybus::Endpoint definition for the respective MQTT topic and not explicitly given in the request object. And the jsonrpc member is ignored and currently not sent.

The request message must be sent on the MQTT topic that is composed of the endpoint name with an additional /req suffix (shorthand for request), e.g. for an endpoint setToolTableRow the topic must be setToolTableRow/req. The result will be returned as a message on the MQTT topic with an additional /res suffix (shorthand for result).

Alternatively, the endpoints could also be configured as write endpoints, which results in exactly the same behaviour, with the single exception that the request message must be sent on a MQTT topic with the /set suffix. The results will be returned on the topic with /res suffix, identical to read endpoints, and with identical format. In that sense, write is just an alias for read.

The payload of the initial request message must be a JSON object as string, which must contain the params member as a JSON array (unless the method has no parameters anyway). The params member must be a JSON array with the method arguments listed as JSON values. The array of method arguments will be passed on to the machine and will be used depending on the Heidenhain machine method. The response message of read or write will contain the return value from the machine method as payload member result, or, if the method call failed, a payload member error which contains the error message.

Example mapping:

2  type: Cybus::Endpoint
3  properties:
4    protocol: Heidenhain
5    connection: !ref heidenhainConnection
6    read:
7      method: setToolTableRow

MQTT payload

The MQTT request payload must be a valid JSON object and can contain two properties:

  • id: (optional) User-defined correlation ID which can be used to identify the response. If this property was given, its value will be returned in the return message

  • params: Array of parameters required for the used method. If the method requires no parameters, this property is optional, too.

Following the example mapping above (method: setToolTableRow), the request payload, sent on topic setToolTableRow/req, needs to be as following:

{ "params": [ "1", { "NAME": "REQUEST-EXAMPLE" } ], "id": "1" }

This modifies the tool table row 1 and sets the field ǸAME of that row to REQUEST-EXAMPLE. The following response will be replied on topic setToolTableRow/res:

On success: { "result": null, timestamp: 123123123, "id": "1" }
On error  : { "error": "<error message>", timestamp: 123123123, "id": "1" }

On success, the result value is a null value since setToolTableRow is defined as void.


Certain Heidenhain methods offers the notification pattern. Notification messages will be published when a certain event is triggered.

Example mapping:

2  type: Cybus::Endpoint
3  properties:
4    protocol: Heidenhain
5    connection: !ref heidenhainConnection
6    subscribe:
7      type: notify
8      method: onToolTableChanged

Heidenhain Methods

Available Heidenhain methods. The long list below shows the function prototypes in pseudo-code to clarify the input and output data types. The function name is identical to the method name (see examples below).

Machine Information


Returns true if the CNC control is connected to the agent.

bool isConnected = isConnected()


Get the version of the Heidenhain SDK which the agent is using for communicating to the machine.

string version = getVersion()


Get the connection state of the connected CNC.

string state =  getState()


Get the CNC up-time.

int ncUpTimeMin = getNcUpTime()


Get the machine up-time.

int machineUpTimeMin = getMachineUpTime()


Get the cumulative spindle run-time the spindle has been running since installation. Parameter is the identifier of the spindle.

int spindleRunningTimeMin = getSpindleRunningTime (int axisId)


Get the machine working time since installation.

int machineRunningTimeMin = getMachineRunningTime()


Returns a json object with the specified information about the machine state

{state, machineRunningTime, machineUpTime, ncUpTime} = getMachineState()


Returns an object with key/value pair for every of the known interfaces of the CNC controller. The value is 1 (true) if the respective interface is available, and 0 (false) if it is not.

object getAvailableInterfaces()


Returns true if the Automatic interface is available at this CNC controller

bool hasAutomaticInterface()


Returns true if the DataAccess interface is available at this CNC controller

bool hasDataAccessInterface()


Returns true if the Error interface is available at this CNC controller

bool hasErrorInterface()


Returns true if the FileSystem interface is available at this CNC controller

bool hasFileSystemInterface()


Returns true if the ItncTable interface is available at this CNC controller

bool hasItncTableInterface()


Returns true if the ProcessData interface is available at this CNC controller

bool hasProcessDataInterface()


Returns true if the AutomaticEvents interface is available at this CNC controller

bool hasAutomaticEvents()


Returns true if the DataAccessEvents interface is available at this CNC controller

bool hasDataAccessEvents()


Returns true if the ErrorEvents interface is available at this CNC controller

bool hasErrorEvents()


Returns true if the MachineEvents interface is available at this CNC controller

bool hasMachineEvents()

Tool and Pocket Table


Read row identified by tool ID (row number) from tool table.

object row = getToolTableRow (string toolId)


Set tool table row. Parameters are the tool ID and an Object of key (column name) - value pairs.

void setToolTableRow (string toolId, object row)


Set the next empty tool table row and link the tool to the next empty pocket table ID.

string pocketId = addLinkedToolTableRow(object row)


DEPRECATED - use removeToolTableRow instead. Alias for removeToolTableRow. Remove the given toolId from the tool table

void removeTool(string toolId)


Remove the tool with the given toolId from the tool table

void removeToolTableRow(string toolId)


Clear the row in the tool table with the given toolId so that it is empty

void clearToolTableRow(string toolId)


Read cell from tool table. Parameters are the tool ID and the column name.

string cell = getToolTableCell (string toolId, string fieldName)


Set tool table cell. Parameters are the tool ID, the column name and the value.

void setToolTableCell (string toolId, string fieldName, string fieldValue)


Get the linked tool ID of the pocket table entry by specifying the pocket table ID (row number).

string toolId = getLinkedToolId (string pocketId)


Link tool to pocket table by specifying the pocket table ID (row number) and the tool ID to be linked.

void linkToolToPocketTable (string pocketId, string toolId)


Unlink tool from pocket table by specifying the pocket table ID of tool to be unlinked.

void unlinkToolFromPocketTable (string pocketId)


Set the next empty tool table row and link the tool to the specified pocket table ID.

void setLinkedToolTableRow(string pocketId, object row)


Read entire pocket table. Return is an array of objects, each representing one pocket table row

array pocketTable = getPocketTable()


Returns the tool table row of the tool which is currently selected in the pocket table at the given pocketId

TableRow getToolTableRowByPocketId(string pocketId)


Removes the tool table row of the tool which is currently selected in the pocket table at the given pocketId

void removeToolTableRowByPocketId(string pocketId)


In the tool table, set the tool entry at the given toolId to the content of the newToolRow object. Additionally, if pocketId is given, link the new tool at the given pocketId

string setTool(string pocketId, string toolId, TableRow newToolRow)


Set the next empty tool table row and link the tool to the next empty pocket table ID.

string pocketId = addLinkedToolTableRow(object row)

Data Access


Set the access mode to gain access to protected data sub trees. Not available for iTNCs.

void setAccessMode (string dataPath, string password)


Read value.

string value = getValue (string dataPath)


Set value.

void setValue (string dataPath, string value)


Read PLC Data.

string value = getPlcData (string memoryType, string memoryAddress)

File System


Transmits the given buffer (of base64 encoded bytes) to the CNC where it should be stored as a file at the given destinationPath.

void transmitFile (string fileBuffer, string destinationPath)


Receives the given file from the CNC. Returns it as base64 (!!) encoded string, not in direct binary or text form.

string receiveFile(string cncFile)


Delete the file at the given path

void deleteFile(string filePath)


Copy the file specified by sourceFilePath to the destination destFilePath

void copyFile(string sourceFilePath, string destFilePath)


Returns the list of entries of the directory at the given directoryPath. The json structure contains the actual path (input argument plus potential prefix), and the list of entries.

object readDirectory(string directoryPath)


Make (create) a new directory at the given path

void makeDirectory(string directoryPath)


Delete (remove) the directory at the given path. Directory must be empty.

void deleteDirectory(string directoryPath)


Delete (remove) all files and directories recursively at the given path. Watch out and use this with care.

object deleteDirectoryRecursively(string directoryPath)

NC Program handling


(Un)select an NC part program for execution.

void selectProgram (int channel, string programName, string startBlockNumber)


Stop executing the active NC part program.

void stopProgram (int channel, bool onBlockEnd)


Cancels the execution of a stopped NC program.

void cancelProgram (int channel)


Set the execution mode.

void setExecutionMode (string executionMode)


Start or restart the specified program.

void startProgram (string programName)


Get the current program execution status.

string programStatus = getProgramStatus()


Get the current DNC mode.

string dncMode = getDncMode()


Execute a Clear Control.

void clearControl()


Set the feed override.

void setOverrideFeed (int percentage)


Set the speed override.

void setOverrideSpeed (int percentage)


Set the rapid override.

void setOverrideRapid (int percentage)


Get the current feed override.

int feed = getOverrideInfoFeed()


Get the current speed override.

int speed = getOverrideInfoSpeed()


Get the current rapid override.

int rapid = getOverrideInfoRapid()

Custom Functions in the Cybus Heidenhain Agent


Returns the version of the Cybus Heidenhain Agent.

string getAgentVersion()


For itnc530 and tnc426, sets the manual monitoring (polling) interval of the tool table.

void setTableMonitorInterval(int32_t seconds)


For itnc530 and tnc426, returns the manual monitoring (polling) interval of the tool table.

int32_t getTableMonitorInterval()


Set the special timeout value that ensures thread-safe access to the Heidenhain SDK methods (only needed for some itnc530 variants)

void setSdkMutexTimeout(int32_t seconds)


Returns the special timeout value that ensures thread-safe access to the Heidenhain SDK methods (only needed for some itnc530 variants)

int32_t getSdkMutexTimeout()


All event methods are available as subscribe operation with type: notify.


Notification on any tool table cell change.

{ toolId, oldRow, newRow } = onToolTableChanged()


Tool in spindle changed event. This event is fired by the CNC when a new tool is placed in the spindle or when the actual tool is removed from the spindle.

{ int toolId, object toolOut, object toolIn, double timestamp } = onToolChanged()


Connection state changed event. Notifies the client application of the connection state changes of the CNC. (_IJHMachineEvents2::onStateChanged)

{ string newState } = onStateChanged()


DNC mode change event.

{ string newDncMode } = onDncModeChanged()


Notification on any pocket table cell change.

{ toolId, oldRow, newRow } = onPocketTableChanged()


Notification on execution switch to another program, subprogram or macro.

string program = onProgramChanged()


Notification on a changed NC program. From _IJHAutomaticEvents3::OnProgramChanged and also _IJHAutomaticEvents3::OnProgramStatusChanged. This event is fired when the CNC program execution status is changed. At itnc530 watch out: The iTNC 530 emits this event when a newly selected program is started and not when the program is selected. Typically this event will be emitted after the OnProgramStatusChanged programEvent DNC_PRG_EVT_STARTED.

{string state, string programPath, string programName} = onNcProgramChanged


Notification on program execution status change.

string programEvent = onProgramStatusChanged()

Commissioning File Example

The long file containing all implemented methods is available for download here: Heidenhain reference commissioning file

Short example file, Download: heidenhain-example.yml

 2# ----------------------------------------------------------------------------#
 3# Commissioning File
 4# ----------------------------------------------------------------------------#
 5# Protocol: Heidenhain
 6# Copyright: Cybus GmbH (2020)
 7# Contact: support@cybus.io
 8# ----------------------------------------------------------------------------#
 9description: >
10  Heidenhain sample commissioning file
13  name: Heidenhain example
14  icon: https://www.cybus.io/wp-content/uploads/2017/10/for-whom1.svg
15  provider: cybus
16  homepage: https://www.cybus.io
17  version: 1.0.0
20  ipAddress:
21    type: string
22    description: The IP address of the CNC machine
23    default:
25  cncType:
26    type: string
27    description: The CNC type; can be tnc640, itnc530, tnc426
28    default: tnc640
30  agentName:
31    type: string
32    description: The name of the Cybus Heidenhain agent on the windows machine
33    default: heidenhain-WIN1234
36  heidenhainConnection:
37    type: Cybus::Connection
38    properties:
39      protocol: Heidenhain
40      connection:
41        domain: edge.cybus
42        agent: !ref agentName
43        ipAddress: !ref ipAddress
44        cncType: !ref cncType
45        plcPassword: <password>
46        usrPassword: <password>
47        tablePassword: <password>
48        sysPassword: <password>
49        connectionStrategy:
50          initialDelay: 5000
51          maxDelay: 30000
52          incrementFactor: 2
54  getVersion:
55    type: 'Cybus::Endpoint'
56    properties:
57      protocol: Heidenhain
58      connection: !ref heidenhainConnection
59      topic: getVersion
60      read:
61        method: getVersion
63  getNcUpTime:
64    type: Cybus::Endpoint
65    properties:
66      protocol: Heidenhain
67      connection: !ref heidenhainConnection
68      topic: getNcUpTime
69      read:
70        method: getNcUpTime
72  getToolTable:
73    type: Cybus::Endpoint
74    properties:
75      protocol: Heidenhain
76      connection: !ref heidenhainConnection
77      topic: getToolTable
78      read:
79        method: getToolTable
81  onToolTableChanged:
82    type: Cybus::Endpoint
83    properties:
84      protocol: Heidenhain
85      connection: !ref heidenhainConnection
86      topic: notify/onToolChanged
87      subscribe:
88        type: notify
89        method: onToolTableChanged
91  onProgramChanged:
92    type: Cybus::Endpoint
93    properties:
94      protocol: Heidenhain
95      connection: !ref heidenhainConnection
96      topic: notify/onProgramChanged
97      subscribe:
98        type: notify
99        method: onProgramChanged

MQTT Examples

MQTT Examples following the example device commissioning file above.


Request --> (MQTT topic) MQTT payload
Response <-- (MQTT topic) MQTT payload

Get SDK Version

--> (getVersion/req) { "params": [], "id": 1 }
<-- (getVersion/res) { "result": "1.6.3", "id": 1 }

Set tool table row

--> (setToolTableRow/req) { "params": ["10", { "NAME": "MY-AWESOME-TOOL", "L": "1", "R":"4" }], "id": 2 }
<-- (setToolTableRow/res) { "result": null, "id": 2 }

Get tool table cell

--> (getToolTableCell/req) { "params": ["10", "NAME"], "id": 3 }
<-- (getToolTableCell/res) { "result": "MY-AWESOME-TOOL", "id": 3 }