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"
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"
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
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:
(number)¶
(integer)¶
(string)¶
(boolean)¶
(array)¶
The schema defines an array with all elements of the type string
.
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
Subscription¶
The subscribe pattern offers the possibility to subscribe to a Heidenhain method. This polls the specified method in a given interval.
Example mapping:
1 2 3 4 5 6 7 8 9 10 | getStateSubscribe: type: Cybus::Endpoint properties: protocol: Heidenhain connection: !ref heidenhainConnection topic: myCustomOutputTopic subscribe: type: poll method: getState 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> }
Read¶
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:
1 2 3 4 5 6 7 | setToolTableRow: type: Cybus::Endpoint properties: protocol: Heidenhain connection: !ref heidenhainConnection read: 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 messageparams
: 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.
Notification¶
Certain Heidenhain methods offers the notification pattern. Notification messages will be published when a certain event is triggered.
Example mapping:
1 2 3 4 5 6 7 8 | onToolTableChangedSubscribe: type: Cybus::Endpoint properties: protocol: Heidenhain connection: !ref heidenhainConnection subscribe: type: notify 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¶
isConnected¶
Returns true if the CNC control is connected to the agent.
bool isConnected = isConnected()
getVersion¶
Get the version of the Heidenhain SDK which the agent is using for communicating to the machine.
string version = getVersion()
getSpindleRunningTime¶
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)
getMachineRunningTime¶
Get the machine working time since installation.
int machineRunningTimeMin = getMachineRunningTime()
getMachineState¶
Returns a json object with the specified information about the machine state
{state, machineRunningTime, machineUpTime, ncUpTime} = getMachineState()
getAvailableInterfaces¶
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()
hasAutomaticInterface¶
Returns true if the Automatic interface is available at this CNC controller
bool hasAutomaticInterface()
hasDataAccessInterface¶
Returns true if the DataAccess interface is available at this CNC controller
bool hasDataAccessInterface()
hasErrorInterface¶
Returns true if the Error interface is available at this CNC controller
bool hasErrorInterface()
hasFileSystemInterface¶
Returns true if the FileSystem interface is available at this CNC controller
bool hasFileSystemInterface()
hasItncTableInterface¶
Returns true if the ItncTable interface is available at this CNC controller
bool hasItncTableInterface()
hasProcessDataInterface¶
Returns true if the ProcessData interface is available at this CNC controller
bool hasProcessDataInterface()
hasAutomaticEvents¶
Returns true if the AutomaticEvents interface is available at this CNC controller
bool hasAutomaticEvents()
hasDataAccessEvents¶
Returns true if the DataAccessEvents interface is available at this CNC controller
bool hasDataAccessEvents()
hasErrorEvents¶
Returns true if the ErrorEvents interface is available at this CNC controller
bool hasErrorEvents()
hasMachineEvents¶
Returns true if the MachineEvents interface is available at this CNC controller
bool hasMachineEvents()
Tool and Pocket Table¶
getToolTableRow¶
Read row identified by tool ID (row number) from tool table.
object row = getToolTableRow (string toolId)
setToolTableRow¶
Set tool table row. Parameters are the tool ID and an Object of key (column name) - value pairs.
void setToolTableRow (string toolId, object row)
addLinkedToolTableRow¶
Set the next empty tool table row and link the tool to the next empty pocket table ID.
string pocketId = addLinkedToolTableRow(object row)
removeTool¶
DEPRECATED - use removeToolTableRow instead. Alias for removeToolTableRow. Remove the given toolId from the tool table
void removeTool(string toolId)
removeToolTableRow¶
Remove the tool with the given toolId from the tool table
void removeToolTableRow(string toolId)
clearToolTableRow¶
Clear the row in the tool table with the given toolId so that it is empty
void clearToolTableRow(string toolId)
getToolTableCell¶
Read cell from tool table. Parameters are the tool ID and the column name.
string cell = getToolTableCell (string toolId, string fieldName)
setToolTableCell¶
Set tool table cell. Parameters are the tool ID, the column name and the value.
void setToolTableCell (string toolId, string fieldName, string fieldValue)
getLinkedToolId¶
Get the linked tool ID of the pocket table entry by specifying the pocket table ID (row number).
string toolId = getLinkedToolId (string pocketId)
linkToolToPocketTable¶
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)
unlinkToolFromPocketTable¶
Unlink tool from pocket table by specifying the pocket table ID of tool to be unlinked.
void unlinkToolFromPocketTable (string pocketId)
setLinkedToolTableRow¶
Set the next empty tool table row and link the tool to the specified pocket table ID.
void setLinkedToolTableRow(string pocketId, object row)
getPocketTable¶
Read entire pocket table. Return is an array of objects, each representing one pocket table row
array pocketTable = getPocketTable()
getToolTableRowByPocketId¶
Returns the tool table row of the tool which is currently selected in the pocket table at the given pocketId
TableRow getToolTableRowByPocketId(string pocketId)
removeToolTableRowByPocketId¶
Removes the tool table row of the tool which is currently selected in the pocket table at the given pocketId
void removeToolTableRowByPocketId(string pocketId)
setTool¶
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)
addLinkedToolTableRow¶
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¶
setAccessMode¶
Set the access mode to gain access to protected data sub trees. Not available for iTNCs.
void setAccessMode (string dataPath, string password)
File System¶
transmitFile¶
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)
receiveFile¶
Receives the given file from the CNC. Returns it as base64 (!!) encoded string, not in direct binary or text form.
string receiveFile(string cncFile)
copyFile¶
Copy the file specified by sourceFilePath to the destination destFilePath
void copyFile(string sourceFilePath, string destFilePath)
readDirectory¶
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)
makeDirectory¶
Make (create) a new directory at the given path
void makeDirectory(string directoryPath)
deleteDirectory¶
Delete (remove) the directory at the given path. Directory must be empty.
void deleteDirectory(string directoryPath)
deleteDirectoryRecursively¶
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¶
selectProgram¶
(Un)select an NC part program for execution.
void selectProgram (int channel, string programName, string startBlockNumber)
stopProgram¶
Stop executing the active NC part program.
void stopProgram (int channel, bool onBlockEnd)
getProgramStatus¶
Get the current program execution status.
string programStatus = getProgramStatus()
Custom Functions in the Cybus Heidenhain Agent¶
setTableMonitorInterval¶
For itnc530 and tnc426, sets the manual monitoring (polling) interval of the tool table.
void setTableMonitorInterval(int32_t seconds)
getTableMonitorInterval¶
For itnc530 and tnc426, returns the manual monitoring (polling) interval of the tool table.
int32_t getTableMonitorInterval()
setSdkMutexTimeout¶
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)
getSdkMutexTimeout¶
Returns the special timeout value that ensures thread-safe access to the Heidenhain SDK methods (only needed for some itnc530 variants)
int32_t getSdkMutexTimeout()
Events¶
All event methods are available as subscribe operation with type: notify.
onToolTableChanged¶
Notification on any tool table cell change.
{ toolId, oldRow, newRow } = onToolTableChanged()
onToolChanged¶
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()
onStateChanged¶
Connection state changed event. Notifies the client application of the connection state changes of the CNC. (_IJHMachineEvents2::onStateChanged)
{ string newState } = onStateChanged()
onPocketTableChanged¶
Notification on any pocket table cell change.
{ toolId, oldRow, newRow } = onPocketTableChanged()
onProgramChanged¶
Notification on execution switch to another program, subprogram or macro.
string program = onProgramChanged()
onNcProgramChanged¶
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
onProgramStatusChanged¶
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | --- # ----------------------------------------------------------------------------# # Commissioning File # ----------------------------------------------------------------------------# # Protocol: Heidenhain # Copyright: Cybus GmbH (2020) # Contact: support@cybus.io # ----------------------------------------------------------------------------# description: > Heidenhain sample commissioning file metadata: name: Heidenhain example icon: https://www.cybus.io/wp-content/uploads/2017/10/for-whom1.svg provider: cybus homepage: https://www.cybus.io version: 1.0.0 parameters: ipAddress: type: string description: The IP address of the CNC machine default: 10.0.0.2 cncType: type: string description: The CNC type; can be tnc640, itnc530, tnc426 default: tnc640 agentName: type: string description: The name of the Cybus Heidenhain agent on the windows machine default: heidenhain-WIN1234 resources: heidenhainConnection: type: Cybus::Connection properties: protocol: Heidenhain connection: domain: edge.cybus agent: !ref agentName ipAddress: !ref ipAddress cncType: !ref cncType plcPassword: <password> usrPassword: <password> tablePassword: <password> sysPassword: <password> connectionStrategy: initialDelay: 5000 maxDelay: 30000 incrementFactor: 2 getVersion: type: 'Cybus::Endpoint' properties: protocol: Heidenhain connection: !ref heidenhainConnection topic: getVersion read: method: getVersion getNcUpTime: type: Cybus::Endpoint properties: protocol: Heidenhain connection: !ref heidenhainConnection topic: getNcUpTime read: method: getNcUpTime getToolTable: type: Cybus::Endpoint properties: protocol: Heidenhain connection: !ref heidenhainConnection topic: getToolTable read: method: getToolTable onToolTableChanged: type: Cybus::Endpoint properties: protocol: Heidenhain connection: !ref heidenhainConnection topic: notify/onToolChanged subscribe: type: notify method: onToolTableChanged onProgramChanged: type: Cybus::Endpoint properties: protocol: Heidenhain connection: !ref heidenhainConnection topic: notify/onProgramChanged subscribe: type: notify method: onProgramChanged |
MQTT Examples¶
MQTT Examples following the example device commissioning file above.
Legend:
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 }