# SINUMERIK

Connectware device driver for Siemens Sinumerik 840Dsl and 828D CNC systems. The driver acts as client for the Sinumerik “Access MyMachine / OPC UA” machine interface.

{% hint style="warning" %}
To be able to access the Sinumerik OPC UA interface the machine requires Sinumerik Operate, a Sinumerik OPC UA license and a compatible OPC UA server version. For information on the machine prerequisites, compatibility & setup please see the [SINUMERIK Access MyMachine / OPC UA Configuration Manual](https://cache.industry.siemens.com/dl/files/643/109772643/att_1001368/v1/840Dsl_828D_OPCUA_config_man_0819_en-US.pdf)
{% endhint %}

#### Some Sinumerik vocabulary

* Tool number (`toolNo`): Sinumerik internal tool number which uniquely identifies each tool
* Tool identifier (`toolIdent`): Tool name. In the tool management each tool is explicitly defined both by its identifier and its duplo number. This means that a tool area can only contain equal tool identifiers with different duplo numbers.
* Duplo number (`duploNo`): Number of replacement (“sister”) tool
* Cutting edges (`numCuttEdges`): Number of cutting edges of a tool. This is not the number of blades but the number of different cut radius along the tool. Most tools have one cutting edge (eg regular drill). Also called D-Number.

## Service Commissioning File Specifics

The following describes the available device specifics for a Sinumerik device. The Cybus Sinumerik OPC UA Reference file can be found in section [Reference Device File](#reference-device-file)

## Connection Settings

The device connection is configured with a resource of type Cybus::Connection. Please note that the Sinumerik driver uses the Connectware OPC UA driver implementation and therefore the same settings apply here.

{% code lineNumbers="true" %}

```yaml
sinumerikConnection:
 type: Cybus::Connection
  properties:
    protocol: Sinumerik
    connection:
      host: '127.0.0.1'
      port: 854
      username: admin
      password: admin
```

{% endcode %}

`protocol`

Required. Must be `Sinumerik`.

`connectionhost`

Required.

For a detailed overview on all available OPC UA `connection` settings see the Connectware [OPC UA Client](https://docs.cybus.io/2-0-6/documentation/industry-protocol-details/opc-ua/opc-ua-client) driver documentation.

[Connection Properties](https://docs.cybus.io/2-0-6/documentation/industry-protocol-details/sinumerik/sinumerikconnection)

## Endpoint settings

Each connection can have several endpoints. They define the operations that are supported.

You define an endpoint by adding a resource of type `Cybus::Endpoint`

They have two key properties:

* An operation
* and a Sinumerik driver method

A Sinumerik endpoint support the following modes of operation:

* Read
* Write
* Polling subscription (subscribe operation with type poll)
* Notify subscription (subscribe operation with type notify)

#### Polling subscription

The `subscribe` pattern offers the possibility to subscribe to a Sinumerik driver method and poll the specified method in a given interval.

Example mapping:

{% code lineNumbers="true" %}

```yaml
machineInfoSubscription:
  type: Cybus::Endpoint
  properties:
    protocol: Sinumerik
    connection: !ref sinumerikConnection
    topic: getMachineInfo
    subscribe:
      type: poll
      method: getMachineInfo # Sinumerik driver method
      pollInterval: 5000
```

{% endcode %}

`propertiesprotocol`

Required. Must be `Sinumerik`

`connection`

Required. Must be a reference to a `Sinumerik` connection

`topic`

Optional. Your MQTT topic to write the data to.

`operation`

Required. Must to be `subscribe`

`type`

Required. Must be `poll`.

`method`

Required. Describes the Sinumerik driver method.

`params`

Optional. Array of method parameter.

`pollInterval`

Optional. Polling interval in milliseconds. Default 1000ms.

### Read

The `read` operation offers the possibility to request a machine action and receive a response. The operation follows the JSON-RPC 2.0 Specification. To make it work you only need to specify a `read` operation on the desired method and send a message on a request-topic (`req`):

Example message:

{% code lineNumbers="true" %}

```yaml
{ 'id': 123, 'params': ['param a', 'param b', 'param c'] }
```

{% endcode %}

Example mapping:

{% code lineNumbers="true" %}

```yaml
getMachineInfo:
  type: Cybus::Endpoint
  properties:
    protocol: Sinumerik
    connection: !ref sinumerikConnection
    read:
      method: getMachineInfo
```

{% endcode %}

endpoint propertiesprotocol

Required. Must be `Sinumerik`

connection

Required. Must be a `Sinumerik` connection.

operation

Required. Must to be `read`.

method

Required. Describes the Sinumerik method.

This configuration will subscribe to `getMachineInfo/req` and publish responses to `getMachineInfo/res`.

### MQTT payload

The MQTT request payload requires two keys:

* `id`: User-defined correlation ID which can be used to identify the response
* `params`: Array of parameters required for the used driver method

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

{% code lineNumbers="true" %}

```yaml
{ 'params': [], 'id': '<any-correlation-id>' }
```

{% endcode %}

This invokes the Sinumerik driver method `getMachineInfo` and returns the following response on topic `getMachineInfo/res`:

{% code lineNumbers="true" %}

```yaml
On success: { 'result': { <machine-infos> }, 'id': '<request-correlation-id>' }
On error: { 'error': '<error>', 'id': '<request-correlation-id>' }
```

{% endcode %}

See the [Examples](#examples) section for further information.

### Write

Endpoints configured with the `write` operation works exactly as endpoints configured with the `read` operation, allowing you to execute Sinumerik methods by sending a message to a set-topic (`set`).

Currently, these endpoints don’t support the return of any result.

Please refer to the Read section for more information.

### Notify subscription

Certain Sinumerik driver methods offer events realized through the `subscribe` operation with type `notify`. Notifications are fired when a certain event is triggered.

{% hint style="warning" %}
This feature is highly unstable and can crash the OPC UA server.
{% endhint %}

Example mapping:

{% code lineNumbers="true" %}

```yaml
sinumerikOnNcProgramChangedSubscription:
  type: Cybus::Endpoint
  properties:
    protocol: Sinumerik
    connection: !ref sinumerikConnection
    subscribe:
      type: notify
      method: onNcProgramChanged

mapping:
  type: Cybus::Mapping
  properties:
    mappings:
      - subscribe:
          endpoint: !ref sinumerikOnNcProgramChanged
        publish:
          topic: 'notify/onNcProgramChanged'
```

{% endcode %}

endpoint propertiesprotocol

Required. Must be `Sinumerik`

connection

Required. Must be a `Sinumerik` connection.

operation

Required. Must to be `subscribe`.

type

Required. Must be `notify`.

method

Required.

[Endpoint Properties](https://docs.cybus.io/2-0-6/documentation/industry-protocol-details/sinumerik/sinumerikendpoint)

## Sinumerik Methods

This section describes the available Sinumerik driver methods. Each method is a specific RPC call which requires certain parameters and provides a defined return. The method paramter must be provides in the request payload in the `params` section. See the [Examples](#examples) section for further information.

Important

Each driver method requires certain access rights on the Sinumerik. The driver automatically sets the required OPC UA access rights for the currently connected OPC UA user. Please make sure the user is allowed to change its access rights. See also method `getMyAccessRights`.

Sinumerik NC variables are described here as:

* `<variable-name>` (\<type>, \<sinumerik-machine-data-reference>): \<description>

Note

NC variable details are found in the Siemens Sinumerik NC variables documentation, see e.g. [SINUMERIK 840D sl NC variables](https://cache.industry.siemens.com/dl/files/139/109769139/att_991204/v1/840Dsl_ncvar_lists_man_0619_en-US.pdf).

### Machine Information

Some machine information

### Get Machine Information

Provides static Sinumerik machine information.

* Method: `getMachineInfo`
* Operation: `subscribe` or `req/res`
* Parameter: none
* Return
  * `nckType` (string, -): NC type
  * `nckVersion` (string, $AN\_NCK\_VERSION): NC version
  * `anLanguageOnHmi` (string, $AN\_LANGUAGE\_ON\_HMI): Current language set on HMI
  * `maskToolManagement` (string, $MC\_TOOL\_MANAGEMENT\_MASK): Channel-specific settings for NCK tool management function
  * `basicLengthUnit` (string, -): Global basic unit
  * `numCuttEdgeParams` (string, -): Number of parameters of a cutting edge in the T/TO module
  * `numCuttEdgeParams_ts` (string, ): Number of monitoring parameters of a cutting edge in the T/TS module
  * `numToolParams_tu` (string, MD 18094: MM\_CC\_TDA\_PARAM ): Number of OEM data of a tool in the T/TU module
  * `numCuttEdgeParams_tu` (string, MD 18096: MM\_CC\_TOA\_PARAM): Number of OEM data of a cutting edge in the T/TUE module.

### Get Machine State

Provides current Sinumerik machine state.

* Method: `getMachineState`
* Operation: `subscribe` or `req/res`
* Parameter: none
* Return
  * `anPoweronState` (string, $AN\_POWERON\_STATE): machine power on state
  * `poweronTime` (string, $AN\_POWERON\_TIME): machine runtime in minutes
  * `licenseStatus` (string, -): Licensing status
  * `nckMode` (string, -): Mode in which the NCK works
  * `sysTimeSinceStartup` (string, -): System run time in seconds since NCK ramp-up
  * `progStatus` (string, DB21-30, DBX35.0 - DBX35.4): Program status
  * `progName` (string, -): Active program name
  * `workPName` (string, -): Active workpiece name
  * `accessLevel` (string, -): Level of the access rights currently set

### Get Spindle Speed

Get spindle speed.

* Method: `getSpindleSpeed`
* Operation: `subscribe` or `req/res`
* Parameter: none
* Return
  * `actualSpeed` (string, $AA\_S\[x]): Spindle speed actual value
  * `commandSpeed` (string, -): Spindle speed desired value

### Get Spindle Feed

Get spindle feed.

* Method: `getSpindleFeed`
* Operation: `subscribe` or `req/res`
* Parameter: none
* Return
  * `actualFeed` (string, -): Current constant cutting rate
  * `commandFeed` (string, -): Constant cutting rate of the master spindle

### On NC program change

The method provides an event when the execution of a NC-file changes.

* Method: `onNcProgramChanged`
* Operation: `notify`
* Parameter: none
* Return
  * `progStatus` (string, DB21-30, DBX35.0 - DBX35.4): NC program state
  * `progName` (string, -): Name of active NC-file
  * `workPName` (string, -): Work piece name

### Tool Interaction

#### Get Tool

Read tool by tool number. Method returns the *essential tool configuration*. See also [Examples](#examples).

* Method: `getTool`
* Method signature: `object tool = getTool (string toolNo)`
* Operation: `subscribe` or `req/res`
* Parameter:
  1. `toolNo` (string): Tool number of tool to read
* Return:
  * `toolNo` (string, ): Internal tool number of the tool
  * `adaptNo` (string, -): Number of adapter defined by system parameter $TC\_ADPx
  * `duploNo` (string, $TC\_TP1): Duplo number (number of replacement tool)
  * `numCuttEdges` (string, $P\_TOOLND): Number of cutting edges of a tool
  * `toolIdent` (string, $TC\_TP2): Tool identifier
  * `toolInfo` (string, $TC\_TP11): Definition of the sub-group to which the tool belongs
  * `toolInMag` (string, $A\_TOOLMN): Current magazine in which the tool is located
  * `toolInPlace` (string, $A\_TOOLMLN): Current location in which the tool is located
  * `toolMon` (string, $TC\_TP9): Type of tool monitoring
  * `toolplace_spec` (string, $TC\_TP7): Magazine location type of tool
  * `toolSearch` (string, $TC\_TP10): Selection of the order of the replacement tools
  * `toolMyMag` (string, $A\_MYMN): Owner magazine of the tool magazine from which the tool was loaded
  * `toolMyPlace` (string, $A\_MYMLN): Owner magazine of the tool - Magazine location from which the tool was loaded
  * `toolsize_left` (string, $TC\_TP3): Tool size to the left in half locations
  * `toolsize_right` (string, $TC\_TP4): Tool size to the right in half locations
  * `toolsize_upper` (string, $TC\_TP5): Tool size upwards in half locations
  * `toolsize_down` (string, $TC\_TP6): Tool size downwards in half locations
  * `toolOverSize` (string, $TC\_TP3 … $TC\_TP6): Tool size as fixed setting (two half locations left & right, one half location top & bottom) (`true`, `false`, `special`)
  * `toolState` (string, $TC\_TP8): Tool state
  * `toolStateLocked` (string, $TC\_TP8.2): Tool state - tool is locked (`true`, `false`)
  * `toolMaxVelo` (string, $TC\_TP\_MAX\_VELO): Maximum speed of the tool if the value is >0. There is no monitoring if no speed limit is defined (=0).
  * `toolMaxAcc` (string, $TC\_TP\_MAX\_ACC): Maximum angular acceleration of the tool if the value is >0. There is no monitoring if no acceleration limit is defined (=0).
  * `lifetime` (string, $TC\_MOP2): Remaining service life in minutes
  * `maxLifetime` (string, $TC\_MOP5): Desired service life
  * `toolType` (string, $TC\_DP1): Tool type
  * `length1` (string, $TC\_DP3): Tool length 1
  * `length2` (string, $TC\_DP4): Tool length 2
  * `radius` (string, $TC\_DP6): Tool radius
  * `wearLength1` (string, $TC\_DP12): Tool wear length 1
  * `wearLength2` (string, $TC\_DP13): Tool wear length 2
  * `wearRadius` (string, $TC\_DP15): Tool wear radius
  * `coolant1` (string, $TC\_DP25.10): Coolant 1 (`on`, `off`)
  * `coolant2` (string, $TC\_DP25.11): Coolant 2 (`on`, `off`)
  * `spindleDirection` (string, $TC\_DP2.8 & $TC\_DP2.9): Spindle direction (`left`, `right`, `off`)
  * `teethCount` (string, $TC\_DPNT): Number of teeth of a cutting edge

#### Get Tool Complete

Read tool by tool number. Method returns the *complete tool configuration*. See also [Examples](#examples).

* Method: `getToolComplete`
* Method signature: `object tool = getToolComplete (string toolNo)`
* Operation: `subscribe` or `req/res`
* Parameter:
  1. `toolNo` (string): Tool number of tool to read
* Return: Method returns all *essential tool information* (see `getTool`), plus
  * `toolCompensationEdgeData` (object, $TC\_DPx): Tool edge offset data. Note: `objectIndex = parameterIndex - 1`
  * `toolSupervisionData` (object, TC\_MOPx): Monitoring data per tool edge. Size given by `numCuttEdgeParams_ts`. Note: `objectIndex = parameterIndex - 1`
  * `toolUserData` (object, $TC\_TPCx): User-defined tool parameter. Size given by `numToolParams_tu`. Keys addressed as `toolUser_1` … `toolUser_n`.
  * `toolUserEdgeData` (object, $TC\_DPCx): User-defined cutting edge parameter. Size given by `numCuttEdgeParams_tu`. Note: `objectIndex = parameterIndex - 1`

#### Get Tools

Read all available tools on the Sinumerik. Method returns *essential tool information* for each tool.

* Method: `getTools`
* Method signature: `object tools = getTools ()`
* Operation: `subscribe` or `req/res`
* Parameter: none
* Return
  * object of `getTool` objects. Key is the tool number.

#### Get Tools Complete

Read all available tools on the Sinumerik. Method returns *complete tool information* for each tool.

* Method: `getToolsComplete`
* Method signature: `object tools = getToolsComplete ()`
* Operation: `subscribe` or `req/res`
* Parameter: none
* Return
  * object of `getToolComplete` objects. Key is the tool number.

**Create Tool**

Create new tool on the Sinumerik and set tool configuration.

* Method: `createTool`
* Method signature: `createTool (toolNo, fields, toolArea)`
* Operation: `subscribe` or `req/res`
* Parameter:
  1. `toolNo` (string): Tool number to be created
  2. `fields` (object): Optional, default = `{}`. Tool configuration to set (see [Set Tool Configuration](#set-tool-configuration))
  3. `toolArea` (string): Optional, default = `1`. Tool area in which the tool should be created.
* Return
  * Status code
    * 0: success
    * 1: Tool area does not exist
    * 2: Tool number out of range
    * 3: Tool number exists already
    * 4: Maximum number of tools reached)

#### Set Tool Configuration

Set or modify the configuration of a tool.

* Method: `setToolFields`
* Method signature: `setToolFields (toolNo, fields)`
* Operation: `subscribe` or `req/res`
* Parameter:
  1. `toolNo` (string): Tool number to be created
  2. `fields` (object): Tool configuration to set
* Return: status code

#### Tool configuration

The tool configuration (`fields`) can be any of the *essential tool configuration* (see return of `getTool` method). Add the setting key to the `fields` object. Additionally any ToolUserData ($TC\_TPCx), ToolCompensationEdgeData, ToolSupervisionData and ToolUserEdgeData parameter can be written by adding the key `toolUser_x`, `toolCompensationEdgeData_x`, `toolSupervisionData_x` and `toolUserEdgeData_x`, where `x` should be replaced by the corresponding parameter number, to the `fields` object.

Example:

{% code lineNumbers="true" %}

```yaml
{ 'fields': { 'toolIdent': 'COOLTOOL', '<more_fields>': '...', 'toolUser_3': '2.3' } }
```

{% endcode %}

See also [Examples](#examples).

#### Set Tool

Convenient method to create a tool, set tool configurations and load the tool into a magazine. If no tool number is given the method searches for the first available tool number and uses this for tool creation. See also [Examples](#examples).

* Method: `setTool`
* Method signature: `string toolNo = setTool (toolNo, toolInMag, toolInPlace, fields)`
* Operation: `subscribe` or `req/res`
* Parameter:
  1. `toolNo` (string): Tool number to be created. Auto-assigned if `toolNo = ""`.
  2. `toolInMag` (string): Magazine number the tool should be loaded to. Not loaded if `toolInMag = ""`.
  3. `toolInPlace` (string): Magazine place the tool should be loaded to. Not loaded if `toolInPlace = ""`.
  4. `fields` (object): Tool configuration to set. (see [Set Tool Configuration](#set-tool-configuration))
* Return
  * `toolNo` (string): Tool number of the created tool

#### Delete Tool

Delete an existing tool.

* Method: `deleteTool`
* Method signature: `deleteTool (toolNo, toolArea)`
* Operation: `subscribe` or `req/res`
* Parameter:
  1. `toolNo` (string): Tool number to be deleted
  2. `toolArea` (string): Optional, default = 1. Tool area in which the tool should be deleted.
* Return
  * Status code
    * 0: success
    * 1: Tool area does not exist
    * 2: Tool number out of range
    * 3: Tool number exists already
    * 6: Tool active

#### Delete Tool and Unload

Delete an existing tool. If the tool is loaded into a magazine, the tool is unloaded prior to deletion.

* Method: `deleteToolAndUnload`
* Method signature: `deleteToolAndUnload (toolNo, toolArea = '1')`
* Operation: `subscribe` or `req/res`
* Parameter:
  1. `toolNo` (string): Tool number to be deleted
  2. `toolArea` (string): Optional, default = 1. Tool area in which the tool should be deleted.
* Return: status code (see `deleteTool`)

#### Get Tools in Magazine

Returns which tools are loaded into the magazine locations (places) for a given magazine.

* Method: `getToolsInMagazine`
* Method signature: `object places = getToolsInMagazine (magazineNo)`
* Operation: `subscribe` or `req/res`
* Parameter:
  1. `magazineNo` (string): Magazine number
* Return
  * `places` (object): Object with magazine places and corresponding tool numbers (0 = no tool loaded)

#### Get Tools in Magazines

Returns which tools are loaded into the magazine locations (places) for all magazines on the Sinumerik.

* Method: `getToolsInMagazines`
* Method signature: `object magazines = getToolsInMagazines ()`
* Operation: `subscribe` or `req/res`
* Parameter: none
* Return
  * `magazines` (object): Object with magazine number and magazine places (object, see `getToolsInMagazine`)

#### Load Tool

Load tool into magazine.

Note

The tool configuration and the magazine configuration need to match in order to successfully load a tool into a magazine, e.g. the tool place type (`toolplace_spec`) needs to match the magazine place type.

* Method: `loadTool`
* Method signature: `loadTool (toolInMag, toolInPlace, toolNo)`
* Operation: `subscribe` or `req/res`
* Parameter:
  1. `toolInMag` (string): Magazine number
  2. `toolInPlace` (string): Magazine place to load
  3. `toolNo` (string): Tool to be loaded
* Return: status code

#### Unload Tool

Unload tool from magazine.

* Method: `unloadTool`
* Method signature: `unloadTool (toolInMag, toolInPlace)`
* Operation: `subscribe` or `req/res`
* Parameter:
  1. `toolInMag` (string): Magazine number
  2. `toolInPlace` (string): Magazine place to unload
* Return: status code

#### On Active Tool Changed

Method provides a notification when the active spindle tool changes.

* Method: `onActiveToolChanged`
* Operation: `notify`
* Parameter: none
* Return
  * `active` (object)
    * `actTNumber` (string): Number of active tool
    * `actToolIdent` (string): Identifier of active tool
    * `actDuploNumber` (string): Duplo number of active tool
    * `actDNumber` (string): Number of active tool edge
  * `previous` (object)
    * `actTNumber` (string): Number of previous tool
    * `actToolIdent` (string): Identifier of previous tool
    * `actDuploNumber` (string): Duplo number of previous tool
    * `actDNumber` (string): Number of previous tool edge

#### On Tool Changed

The method provides an event on any *essential tool configuration* change, i.e. tool is added, altered or removed.

* Method: `onToolChanged`
* Operation: `notify`
* Parameter: none
* Return
  * `toolNo` (string): Tool number of changed tool
  * `fields` (object): Tool configuration (see return of `getTool`)
  * `previousFields` (object): Previous tool configuration (see return of `getTool`)

#### On Tool Complete Changed

The method provides an event on any *complete tool configuration* change, i.e. tool is added, altered or removed.

* Method: `onToolCompleteChanged`
* Operation: `notify`
* Parameter: none
* Return
  * `toolNo` (string): Tool number of changed tool
  * `fields` (object): Tool configuration (see return of `getToolComplete`)
  * `previousFields` (object): Previous tool configuration (see return of `getToolComplete`)

#### On Magazine Tool Changed

The method provides an event on any magazine tool change, i.e. when a tool is loaded/unloaded to a magazine.

* Method: `onMagazineToolChanged`
* Operation: `notify`
* Parameter: none
* Return
  * `magNo` (string, -): Magazine number
  * `magPlace` (string, -): Magazine location
  * `toolNo` (string, -): Tool number which loaded/unloaded to/from this location

### Magazine Information

#### Get Magazine

Method returns information about a specific magazine.

* Method: `getMagazine`
* Method signature: `object magazine = getMagazine (magNo)`
* Operation: `subscribe` or `req/res`
* Parameter:
  1. `magNo` (string): Magazine number to read
* Return
  * `magNo` (string, -): Magazine number
  * `magActPlace` (string, $TC\_MAP8): Current magazine position
  * `magNrPlaces` (string, -): Number of real locations (in chain magazine) or number of slots (in box magazine)
  * `magCmdState` (string, -): Command state of the magazine
  * `magIdent` (string, $TC\_MAP1): Identifier of the magazine
  * `magKind` (string, $TC\_MAP1): Type of the magazine
  * `magState` (string, $TC\_MAP3): State of the magazine

#### Get Magazines

Method returns information about all available magazine.

* Method: `getMagazines`
* Method signature: `object magazines = getMagazines ()`
* Operation: `subscribe` or `req/res`
* Parameter: none
* Return
  * object of `getMagazine` objects. Key is the magazine number.

### File System

#### Read File

Read a file from the Sinumerik file system.

* Method: `readFile`
* Method signature: `{ path, data } = readFile (path)`
* Operation: `subscribe` or `req/res`
* Parameter:
  1. path (string): File path including filename, addressable either as absolute or relative path (e.g. “Sinumerik/FileSystem/Sub Program/foobar.SPF” or “Sub Program/foobar.SPF”)
* Return
  * `path` (string): Absolute file path
  * `data` (string): Base64 encoded file content

#### Write File

Write file to Sinumerik file system. Directories are created automatically from given file path if non existing on the Sinumerik. By default, existing files are not overwritten. If you require files to be overwritten, specify the `overwrite` flag.

* Method: `writeFile`
* Method signature: `writeFile (filepath, data, overwrite)`
* Operation: `subscribe` or `req/res`
* Parameter:
  1. `path` (string): File path including filename, addressable either as absolute or relative path (e.g. “Sinumerik/FileSystem/Sub Program/foobar.SPF” or “Sub Program/foobar.SPF”)
  2. `data` (string): Base64 encoded file data
  3. `overwrite` (bool): Optional, default: false. Overwrite existing file.
* Return: status code

#### Read Directory

Get list of files and subdirectories from directory.

* Method: `readDirectory`
* Method signature: `{ path, entries } = readDirectory(path)`
* Operation: `subscribe` or `req/res`
* Parameter:
  1. `path` (string): Directory path, addressable either as absolute or relative path (e.g. “Sinumerik/FileSystem/Sub Program” or “Sub Program”)
* Return
  * `path`: (string) Absolute directory path
  * `entries`: (array) Directory entries

#### Delete Directory

Delete directory. By default, directories that have any content (files/subdirectories) are not deleted. If you require to delete directories including content recursively, specify the `recursive` flag (use with care!).

* Method: `deleteDirectory`
* Method signature: `deleteDirectory (directoryPath, recursive)`
* Operation: `subscribe` or `req/res`
* Parameter:
  1. `path` (string): Directory path, addressable either as absolute or relative path (e.g. “Sinumerik/FileSystem/Sub Program” or “Sub Program”)
  2. `recursive` (bool): Optional, default: false. Delete directories including any content recursively.
* Return: Status code

## Access Rights Management

### Get User Access Rights

Read OPC UA access rights of the current OPC UA user.

* Method: `getMyAccessRights`
* Operation: `subscribe` or `req/res`
* Parameter: none
* Return: Access rights

### Give User Access

Set accesss rights for current OPC UA user. Please note that all driver methods automatically set their required access rights.

* Method: `giveUserAccess`
* Operation: `subscribe` or `req/res`
* Parameter:
  1. `level` (string): User access level
* Return: Status code

## Examples

The examples are using the Sinumerik Reference Device File below. Thus, the MQTT topics might differ in your application but the payload needs to be the same (as long as no JSONata rules are being used).

### Get Tool Complete

Example showing how to read the complete tool configuraton of tool number 1.

* Method: `getToolComplete`
* Operation: `req/res`

Request on MQTT topic “sinumerik-opcua/\<machine-ip>/getToolComplete/req”

{% code lineNumbers="true" %}

```yaml
{ 'id': 1, 'params': ['1'] }
```

{% endcode %}

Example response on MQTT topic “sinumerik-opcua/\<machine-ip>/getToolComplete/res”

{% code lineNumbers="true" %}

```yaml
{
  'id': 1,
  'timestamp': 1589978193302,
  'result':
    {
      'toolNo': '1',
      'toolIdent': 'SUPER_DRILL_7',
      'duploNo': '1',
      'numCuttEdges': '1',
      'toolInMag': '2',
      'toolInPlace': '15',
      'toolState': '131',
      'toolplace_spec': '1',
      'toolMaxAcc': '0',
      'toolMaxVelo': '0',
      'adaptNo': '0',
      'toolInfo': '0',
      'toolMyMag': '2',
      'toolMyPlace': '15',
      'toolSearch': '0',
      'toolMon': '0',
      'toolStateLocked': 'false',
      'toolOverSize': 'true',
      'toolsize_down': 1,
      'toolsize_left': 1,
      'toolsize_right': 1,
      'toolsize_upper': 1,
      'lifetime': '0',
      'maxLifetime': '0',
      'toolType': '205',
      'length1': '50',
      'length2': '0',
      'radius': '25',
      'wearLength1': '0',
      'wearLength2': '0',
      'wearRadius': '0',
      'coolant1': 'on',
      'coolant2': 'off',
      'spindleDirection': 'right',
      'toolCompensationEdgeData':
        {
          '0': '205',
          '1': '9',
          '2': '50',
          '3': '0',
          '4': '0',
          '5': '25',
          '6': '0',
          '7': '0',
          '8': '0',
          '9': '0',
          '10': '0',
          '11': '0',
          '12': '0',
          '13': '0',
          '14': '0',
          '15': '0',
          '16': '0',
          '17': '0',
          '18': '0',
          '19': '0',
          '20': '0',
          '21': '0',
          '22': '0',
          '23': '0',
          '24': '256',
          '25': '0',
          '26': '0',
          '27': '0',
          '28': '0',
          '29': '0',
          '30': '0',
          '31': '0',
          '32': '0',
          '33': '0',
          '34': '0',
        },
      'toolSupervisionEdgeData': { '0': '0', '1': '0', '2': '0', '3': '0', '4': '0', '5': '0', '6': '0', '7': '0', '8': '0' },
      'toolUserData':
        {
          'toolUser_1': '0',
          'toolUser_2': '10',
          'toolUser_3': '0',
          'toolUser_4': '0',
          'toolUser_5': '0',
          'toolUser_6': '0',
          'toolUser_7': '0',
          'toolUser_8': '0',
          'toolUser_9': '0',
          'toolUser_10': '0',
        },
      'toolUserEdgeData': { '0': '0', '1': '0', '2': '0', '3': '0', '4': '0', '5': '0', '6': '0', '7': '0' },
    },
}
```

{% endcode %}

### Set Tool

Example showing how to create a new tool and to set its configuration. In the example we do not require to set a specific tool number but rather let the driver choose the next available tool number automatically.

* Method: `setTool`
* Operation: `req/res`

Request on MQTT topic “sinumerik-opcua/\<machine-ip>/setTool/req”

{% code lineNumbers="true" %}

```yaml
{
  "id": 2
  "params": [
    "",           // No specific tool number required
    "",           // We do not want to load the tool into magazine number
    "",           // We do not want to load the tool into magazine place
    {
      "toolIdent": "MY_NEW_TOOL",
      "toolType": "900",
      "length1": "125.5",
      "radius": "3.24,
      "spindleDirection": "left",
      "coolant1": "on",
      "toolOverSize": "true",
      "toolUser_2": "2.3"
    }
  ]
}
```

{% endcode %}

Example response on MQTT topic “sinumerik-opcua/\<machine-ip>/setTool/res”

{% code lineNumbers="true" %}

```yaml
{
  "id": 2,
  "timestamp": 1589978193302,
  "result": "2"               // Driver created tool number 2
}
```

{% endcode %}

Here the driver successfully created a new tool using the next available tool number 2.

## Reference Device File

Sinumerik OPC UA Reference File.

{% file src="<https://639096190-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfDpOJO2upcq5EpoSahvK%2Fuploads%2Fgit-blob-e2c3c529dda7a2ba8872ef9bdfb7cddda705144d%2Fsinumerik-reference.yml?alt=media>" %}

{% code title="sinumerik-reference.yml" lineNumbers="true" %}

```yaml
---
# ----------------------------------------------------------------------------#
# Cybus Connectware Device Commissioning File
# Device: Sinumerik OPC UA Reference Device
# ----------------------------------------------------------------------------#
# Copyright: Cybus GmbH (2020)
# Contact: support@cybus.io
# ----------------------------------------------------------------------------#
description: >
  Sinumerik OPC UA Reference Device

metadata:
  name: Sinumerik 840D
  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:
  host:
    type: string
    default: 192.168.0.1

  port:
    type: integer
    default: 4840

  username:
    type: string
    default: ''

  password:
    type: string
    default: ''

resources:
  sinumerikConnection:
    type: Cybus::Connection
    properties:
      protocol: Sinumerik
      connection:
        host: !ref host
        port: !ref port
        username: !ref username
        password: !ref password

  # Machine information

  # Machine info
  getMachineInfoSubscription:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      subscribe:
        type: poll
        pollInterval: 5000
        method: getMachineInfo

  getMachineInfo:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: getMachineInfo

  # Machine state
  # { anPoweronState,
  #   poweronTime,
  #   licenseStatus,
  #   nckMode,
  #   sysTimeSinceStartup,
  #   progStatus,
  #   progName } = getMachineState()
  getMachineStateSubscription:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      subscribe:
        type: poll
        pollInterval: 5000
        method: getMachineState

  getMachineState:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: getMachineState

  # On NC-Program change
  # { progStatus, progName } = onNcProgramChanged()
  onNcProgramChangedSubscription:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      subscribe:
        type: poll
        method: onNcProgramChanged

  # Spindle Speed
  # { actSpeed, cmdSpeed } = getSpindleSpeed()
  getSpindleSpeed:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: getSpindleSpeed

  # Spindle Feed
  # { acConstCutS, cmdConstCutSpeed } = getSpindleFeed
  getSpindleFeed:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: getSpindleFeed

  # TOOLS

  # Get tool
  # tool = getTool(toolNo)
  getTool:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: getTool

  # Get complete tool
  # tool = getToolComplete(toolNo)
  getToolComplete:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: getToolComplete

  # Read tools
  # tools = getTools()
  getTools:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: getTools

  # Read complete tools
  # tools = getToolsComplete()
  getToolsComplete:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: getToolsComplete

  # Get tools in magazine
  # toolsInMagazine = getToolsInMagazine(toolNo)
  getToolsInMagazine:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: getToolsInMagazine

  # Get tools in magazines
  # toolsInMagazine = getToolsInMagazines()
  getToolsInMagazines:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: getToolsInMagazines

  # Create tool
  # createTool(toolNo, fields)
  createTool:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: createTool

  # Set tool fields
  # setToolFields(toolNo, fields)
  setToolFields:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: setToolFields

  # Set tool
  # toolNo = setTool(toolNo, toolInMag, toolinPlace, fields)
  setTool:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: setTool

  # Delete tool
  # deleteTool(toolNo)
  deleteTool:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: deleteTool

  # Delete Tool And Unload
  # deleteToolAndUnload(toolNo)
  deleteToolAndUnload:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: deleteToolAndUnload

  # Load tool into magazine
  # loadTool(toolInMag, toolInPlace, toolNo)
  loadTool:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: loadTool

  # Unload tool from magazine
  # unloadTool(toolInMag, toolInPlace)
  unloadTool:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: unloadTool

  # On active tool change
  # { active: {...}, previous: {...} } = onActiveToolChanged()
  onActiveToolChangedSubscription:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      subscribe:
        type: poll
        method: onActiveToolChanged

  # On tool change
  # { toolNo, fields, previousFields } = onToolChanged()
  onToolChangedSubscription:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      subscribe:
        type: poll
        method: onToolChanged

  # On magazine tool change
  # { magNo, magPlace, toolNo } = onMagazineToolChanged()
  onMagazineToolChangedSubscription:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      subscribe:
        type: poll
        method: onMagazineToolChanged

  # MAGAZINES

  # Get magazine
  # magazine = getMagazine(magNo)
  getMagazine:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: getMagazine

  # Get magazines
  # magazines = getMagazines()
  getMagazines:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: getMagazines

  # FILES

  # Read file
  # { path, data } = readFile(path)
  readFile:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: readFile

  # Write file
  # path = writeFile(path, data, overwrite)
  writeFile:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: writeFile

  # Read directory
  # { path, entries } = readDirectory(path)
  readDirectory:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: readDirectory

  # Delete directory
  # path = deleteDirectory(path)
  deleteDirectory:
    type: Cybus::Endpoint
    properties:
      protocol: Sinumerik
      connection: !ref sinumerikConnection
      read:
        method: deleteDirectory
```

{% endcode %}
