# Device Variables Usage

{% embed url="<https://www.youtube.com/watch?v=qvsAqdnxvmo&t=2s&ab_channel=LicenseSpringSoftware>" %}

Device variables play a crucial role in LicenseSpring's SDKs by facilitating the exchange of data from devices to the vendor platform.

This mechanism allows developers and administrators to gather real-time device-specific information, empowering them to make informed decisions and tailor licensing strategies based on accurate insights.

The aim of this section is to provide you with a comprehensive understanding of effectively utilizing device variables.

### Prerequisites

{% stepper %}
{% step %}

### Complete the Getting Started tutorial

You should have completed the [**Getting Started**](/sdks/tutorials/getting-started.md) tutorial, including:

* Initialized `LicenseManager` (or `LicenseHandler`) with your configuration using the appropriate settings.
* Created a `LicenseID` using either `LicenseID::fromKey` or `LicenseID::fromUser` function, depending on the activation method you prefer.
* Activated a license of any type.
* Implemented routine local and online checks within the application.
  {% endstep %}
  {% endstepper %}

### Understanding Device Variable Usage

Some examples of scenarios where device variables are useful:

#### Hardware Specifications

Device variables can be utilized to capture and transmit hardware specifications, such as CPU type, RAM size, and storage capacity.

This information can be invaluable for tailoring licenses based on the user's hardware capabilities.

#### Tracking User Registration Data

User registration data includes names and user information, which can be sent and kept track of on the LicenseSpring platform using these variables.

This enables you to gather and manage essential user details directly within the licensing framework, streamlining administrative tasks and enhancing user experience.

#### User Preferences

Store user preferences, settings, and configurations using device variables to create a more personalized and seamless user experience.

### Adding Device Variables

Integrating device variables on existing licenses can be done in three different ways.

{% stepper %}
{% step %}

### Adding a name-value pair

{% tabs %}
{% tab title="C++" %}

```cpp
// 1. Adding a name-value pair
license->addDeviceVariable("Name", "Value", false);

// Finally, to send our variables to the LicenseSpring server:
license->sendDeviceVariables();
```

{% endtab %}

{% tab title="C#" %}

```csharp
// 1. Adding a name-value pair
license.AddDeviceVariable("Name", "Value");

// Finally, to send our variables to the LicenseSpring server:
license.SendDeviceVariables();
```

{% endtab %}

{% tab title="Swift" %}

```swift
// Swift: send a dictionary of variables
try license.sendDeviceVariables([
    "Name1": "Value1",
    "Name2": "Value2"
])
```

{% endtab %}

{% tab title="Python" %}

```python
# 1. Adding name-value pairs (directly supported within set_device_variables)
license.set_device_variables({"a":"b","c":"d"})

# send device variables to LS server
license.send_device_variables()
```

{% endtab %}

{% tab title="Go" %}

```go
// Go SDK v2: construct custom fields and send
customFields := []core_request.CustomFields{}
customFields = append(customFields, core_request.CustomFields{Name: "name", Value: "device1"})
err = lh.SendDeviceData(ctx, customFields)
```

{% endtab %}

{% tab title="Java" %}

```java
String licenseKey = "<SAMPLE-KEY>";
String licenseIdentity = LicenseIdentity.fromKey(licenseKey);
DeviceVariables variables = DeviceVariables.builder()
  .variable("var1", "value1")
  .variable("var2", "value2")
  .build();

licenseManager.trackVariables(licenseIdentity, variables.getVariables());
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const license = licenseManager.loadLicense();
// set variables locally; second parameter determines whether to save locally
license.setDeviceVariablesLocal({ key1: 'value1' }, true);
// sync updated device variables with the server; boolean determines whether to save locally
license.setDeviceVariables(true);
```

{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

### Adding a DeviceVariable object

{% tabs %}
{% tab title="C++" %}

```cpp
// 2. Adding a DeviceVariable object
DeviceVariable deviceVar = DeviceVariable("Name", "Value");
license->addDeviceVariable(deviceVar, false);

// Finally, to send our variables to the LicenseSpring server:
license->sendDeviceVariables();
```

{% endtab %}

{% tab title="C#" %}

```csharp
// 2. Adding a DeviceVariable object
DeviceVariable deviceVariable = DeviceVariable("Name", "Value");
license.AddDeviceVariable(deviceVar);

// Finally, to send our variables to the LicenseSpring server:
license.SendDeviceVariables();
```

{% endtab %}

{% tab title="Swift" %}

```swift
// Swift: send a dictionary of variables
try license.sendDeviceVariables([
    "Name1": "Value1",
    "Name2": "Value2"
])
```

{% endtab %}

{% tab title="Python" %}

```python
# Using set_device_variables with a mapping supports adding variables
license.set_device_variables({"a":"b","c":"d"})

# send device variables to LS server
license.send_device_variables()
```

{% endtab %}

{% tab title="Go" %}

```go
// Go SDK v2: construct custom fields and send
customFields := []core_request.CustomFields{}
customFields = append(customFields, core_request.CustomFields{Name: "name", Value: "device1"})
err = lh.SendDeviceData(ctx, customFields)
```

{% endtab %}

{% tab title="Java" %}

```java
String licenseKey = "<SAMPLE-KEY>";
String licenseIdentity = LicenseIdentity.fromKey(licenseKey);
DeviceVariables variables = DeviceVariables.builder()
  .variable("var1", "value1")
  .variable("var2", "value2")
  .build();

licenseManager.trackVariables(licenseIdentity, variables.getVariables());
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const license = licenseManager.loadLicense();
// set variables locally; second parameter determines whether to save locally
license.setDeviceVariablesLocal({ key1: 'value1' }, true);
// sync updated device variables with the server; boolean determines whether to save locally
license.setDeviceVariables(true);
```

{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

### Adding multiple DeviceVariable objects via vector/array

{% tabs %}
{% tab title="C++" %}

```cpp
// 3. Adding multiple DeviceVariable objects via vector
std::vector<DeviceVariable> deviceVariables = {
    DeviceVariable("Name1", "Value1"),
    DeviceVariable("Name2", "Value2")
};
license->addDeviceVariables(deviceVariables);

// Finally, to send our variables to the LicenseSpring server:
license->sendDeviceVariables();
```

{% endtab %}

{% tab title="C#" %}

```csharp
// 3. Adding multiple DeviceVariable objects via array
DeviceVariable[] devVariables = {
    new DeviceVariable("name1", "value1"),
    new DeviceVariable("name2", "value2")
};
license.AddDeviceVariables(devVariables);

// Finally, to send our variables to the LicenseSpring server:
license.SendDeviceVariables();
```

{% endtab %}

{% tab title="Swift" %}

```swift
// Swift: send a dictionary of variables
try license.sendDeviceVariables([
    "Name1": "Value1",
    "Name2": "Value2"
])
```

{% endtab %}

{% tab title="Python" %}

```python
# 1,2,3 are directly supported within set_device_variables
license.set_device_variables({"a":"b","c":"d"})

# send device variables to LS server
license.send_device_variables()
```

{% endtab %}

{% tab title="Go" %}

```go
// Go SDK v2
customFields := []core_request.CustomFields{}
customFields = append(customFields, core_request.CustomFields{Name: "name", Value: "device1"})
err = lh.SendDeviceData(ctx, customFields)
```

{% endtab %}

{% tab title="Java" %}

```java
String licenseKey = "<SAMPLE-KEY>";
String licenseIdentity = LicenseIdentity.fromKey(licenseKey);
DeviceVariables variables = DeviceVariables.builder()
  .variable("var1", "value1")
  .variable("var2", "value2")
  .build();

licenseManager.trackVariables(licenseIdentity, variables.getVariables());
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const license = licenseManager.loadLicense();
// the following sets the variables on the license object; 
// the second (boolean) parameter determines whether to save the changes to the license file:
license.setDeviceVariablesLocal({ key1: 'value1' }, true);
// the following syncs the updated device variables with the server;
// the boolean parameter determines whether to save the changes to the license file:
license.setDeviceVariables(true);
```

{% endtab %}
{% endtabs %}
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Note: To update a device variable, you can simply add the device variable with the same name and its updated value.
{% endhint %}

Device variables can also be set on license activation:

{% tabs %}
{% tab title="C#" %}

```csharp
DeviceVariable[] deviceVariables = {
    new DeviceVariable("name1", "value1"),
    new DeviceVariable("name2", "value2")
};
LicenseID id = LicenseID.FromKey("license-key-goes-here");
ILicense license = licenseManager.ActivateLicense(id, deviceVariables);

// Offline activation is also supported.
string offlineActivationFile = licenseManager.GetOfflineActivationFile(id, deviceVariables);
```

{% endtab %}

{% tab title="C++" %}

```cpp
std::vector<DeviceVariable> deviceVariables = { {"name1", "value1"}, {"name2", "value2"} };
auto licenseId = LicenseID::fromKey("license-key-here");

auto license = licenseManager->activateLicense(licenseId, deviceVariables);

// Offline activation is also supported.
std::wstring offlineActivationFile = licenseManager->createOfflineActivationFile(licenseId, deviceVariables);
```

{% endtab %}

{% tab title="Python" %}

```python
# Only supports offline activations
req_folder = "req_folder_path"

lm.create_offline_activation_file(license_id, req_folder, device_variables={"a":"b","c":"d"})
```

{% endtab %}

{% tab title="Java" %}

```java
String licenseKey = "<SAMPLE-KEY>";
String licenseIdentity = LicenseIdentity.fromKey(licenseKey);
DeviceVariables variables = DeviceVariables.builder()
  .variable("var1", "value1")
  .variable("var2", "value2")
  .build();

ActivateOfflineParams params = ActivateOfflineParams
  .builder()
  .variables(variables)
  .build();
  
String file = licenseManager.offlineActivationFile(licenseIdentity, null, params);
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const offlineActivationPayload = licenseManager.createOfflineActivationPayload({ variables: { key1: 'value1' } });
```

{% endtab %}
{% endtabs %}

### Accessing Device Variables

To locate the device variables through the vendor platform, first navigate to your license then to the "Devices" tab.

![Device tab where device variables are found.](/files/9332b4fed481c1cf82c1f3e7cbee43b1385dbe47)

Next, click on the device variables button to open a list of the device's device variables.

![Device Variables button](/files/d40fe173b5081cda9d4d9ae3944a4b3009bbb126)

{% tabs %}
{% tab title="C++" %}

```cpp
std::vector<DeviceVariable> device_vec = license->getDeviceVariables(true);
```

{% endtab %}

{% tab title="C#" %}

```csharp
DeviceVariable[] devVariables = license.GetDeviceVariables(true);
```

{% endtab %}

{% tab title="Swift" %}

```swift
// Just access variables (updated after latest online check).
let existingVariables = license.deviceVariables

// Request variables from the LicenseSpring platform.
let updatedVariables = try license.requestDeviceVariables()
```

{% endtab %}

{% tab title="Python" %}

```python
device_var_list = license.get_device_variables(get_from_be=True)

print(device_var_list)
```

{% endtab %}

{% tab title="Go" %}

```go
// Go SDK v2
vars, err := lh.GetDeviceVariables(ctx, true)
```

{% endtab %}

{% tab title="Java" %}

```java
// Offline: Retrieve Device Variables
License license = licenseManager.getCurrent();
LicenseData data = license.getData();
List<DeviceVariable> variables = data.getVariables();

// Online: Retrieve Device Variables
LicenseIdentity identity = license.getIdentity();
List<DeviceVariable> variables = licenseManager.getVariables(identity);
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const license = licenseManager.loadLicense();
// the following line syncs device variables by fetching them from the server
await license.getDeviceVariables();
const variables = license.getDeviceVariablesLocal();
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Note: The SDKs can retrieve device variables from either the local license or from the backend. The Boolean parameter passed into the `getDeviceVariables` function decides where they are retrieved from:

* `true` gets the device variables from the backend.
* `false` gets them from the local license.

By default, this parameter is `false`. If no parameter is passed to this method, it will retrieve from the local license.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.licensespring.com/sdks/tutorials/best-practices/device-variables-usage.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
