Registering a sensor in an TTN application via API

Not forgotten you, at worst can look at it after supper

Good morning descartes,

Can you please have a look today at my code and give me a useful tip to solve my issue?

Kind regards
Imran Khan

Not sure if it will be today - in the end I had to backup 5Tb so I could re-install from a clean disk - but Iā€™ll leave it open on my desktop to remind me.

Ah, hang on, whilst copying & pasting this over so I can have this open I see that you have replaced the field mask static values with variables for no apparent reason - I have no idea what effect this will have but itā€™s not in the Python (which Iā€™ve confirmed works) and itā€™s not in the documentation either, although thatā€™s not explicitly shown but there is an example here:

https://www.thethingsindustries.com/docs/getting-started/api/#multi-step-actions

So,:

'field_mask' => [
	 'paths' => [
			'eu1.cloud.thethings.network',
			'eu1.cloud.thethings.network',
			'eu1.cloud.thethings.network',
			$this->devEui,
			$this->appEui,
			$this->deviceId
			],
	 ],
];

should be

'field_mask' => [
	 'paths' => [

  "join_server_address", 
  "network_server_address", 
  "application_server_address", 
  "description", 
  "name", 
  "ids.dev_eui", 
  "ids.join_eui"

	 ],
];

But Iā€™m yet to figure out the details of the field mask, I suspect thatā€™s what itā€™s being told to return. But certainly giving it data rather than field names isnā€™t going to help.

Good morning descartes,
In my last attempt, I set the field mask the same as you suggested. The response of all the Post requests shows a success message but the device join to the TTN is not happening. The device tries all the time to find the network.
If you see the given above screenshots, The Post request is unable to write LoRaWAN version, Regional parameters version, and Frequency plan. The Activation mode also shows ABP activation.

Kind regards,
Imran Khan

Did you correct the field masks for the other three requests too?

Yes, I corrected all the four field masks for all the four Post requests.

And the result was ā€¦

The device got registered in the TTN but there are many field which are left empty. Network layer is left empty as given below.
ns
OTAA is also not activated and the device is unable to make a join.
The join server settings look fine though but device is unable to join the network. The Join server screenshot is given below.
js

OK, as per other thread, Iā€™m due some light relief today, let me see what I can rustle up!

Thanks :blush:

OK, bit of boring debugging later and I found the culprit by comparing the Python JSON to the PHP JSON:

$data3 = [
ā€˜end_deviceā€™ => [
ā€˜multicateā€™ => False,

mulitcate should be multicast

and

ā€˜field_maskā€™ => [
ā€˜pathā€™ => [

path should be paths

Hereā€™s the whole lot, partial reworked as the use of data1, data2 etc is banned under the Geneva Convention:

<?php

$apiKey = "NNSXS.T0P.53CR3T.AP1.K3Y"

$app_id = "descartes-test01v3";
$app_eui = "0000000000000000";

$device_id = "otaa-test-setup-55";
$dev_eui = "9999999999999955";
$app_key = "19BEC34220EBF366070B59F723F234BE";

$idServer = [
	'end_device' => [
		'ids' => [
			'device_id' => $device_id,
			'dev_eui' => $dev_eui,
			'join_eui' => $app_eui
		],
		'join_server_address' => 		'eu1.cloud.thethings.network',
		'network_server_address' => 	'eu1.cloud.thethings.network',
		'application_server_address' => 'eu1.cloud.thethings.network',
		'name' => $device_id
	],
	'field_mask' => [
		'paths' => [
			'join_server_address', 'network_server_address', 'application_server_address', 'ids.dev_eui', 'ids.join_eui', 'name'
		]
	]
];

$joinServer = [
	'end_device' => [
		'ids' => [
			'device_id' => $device_id,
			'dev_eui' => $dev_eui,
			'join_eui' => $app_eui
		],
		'network_server_address' => 	'eu1.cloud.thethings.network',
		'application_server_address' => 'eu1.cloud.thethings.network',
		'network_server_kek_label' => '',
		'application_server_kek_label' => '',
		'application_server_id' => '',
		'net_id' => Null,
		'root_keys' => [
			'app_key' => [
				'key' => $app_key
			],
		],
	],
	'field_mask' => [
		'paths' => [
			 'network_server_address', 'application_server_address', 
			 'ids.device_id', 'ids.dev_eui', 'ids.join_eui', 
			 'network_server_kek_label', 'application_server_kek_label', 
			 'application_server_id', 'net_id', 'root_keys.app_key.key'
		],
	]
];

$networkServer = [
	'end_device' => [
		'multicast' => False,
		'supports_join' => True,
		'lorawan_version' => "MAC_V1_0_2",
		'ids' => [
			'device_id' => $device_id,
			'dev_eui' => $dev_eui,
			'join_eui' => $app_eui
		],
		'mac_settings' => [
			'supports_32_bit_f_cnt' => True
		],
		'supports_class_c' => False,
		'supports_class_b' => False,
		'lorawan_phy_version' => "PHY_V1_0_2_REV_B",
		'frequency_plan_id' => "EU_863_870_TTN"
	 ],
	'field_mask' => [
		'paths' => [
			'multicast', 'supports_join', 'lorawan_version',
			'ids.device_id', 'ids.dev_eui', 'ids.join_eui',
			'mac_settings.supports_32_bit_f_cnt',
			'supports_class_c', 'supports_class_b',
			'lorawan_phy_version', 'frequency_plan_id' 
		]
	]
];


$applicationServer = [
	'end_device' => [
		'ids' => [
			'device_id' => $device_id,
			'dev_eui' => $dev_eui,
			'join_eui' => $app_eui
		],
	],
	'field_mask' => [
		'paths' => [
			'ids.device_id', 'ids.dev_eui', 'ids.join_eui'
		]
	]
];
		
$data_end_device= json_encode($idServer);
$data_join_server = json_encode($joinServer);
$data_network_server = json_encode($networkServer);
$data_application_server = json_encode($applicationServer);

$url1 = 'https://eu1.cloud.thethings.network/api/v3/applications/'.$app_id.'/devices';
$url2 = 'https://eu1.cloud.thethings.network/api/v3/js/applications/'.$app_id.'/devices';
$url3 = 'https://eu1.cloud.thethings.network/api/v3/ns/applications/'.$app_id.'/devices';
$url4 = 'https://eu1.cloud.thethings.network/api/v3/as/applications/'.$app_id.'/devices';

$authorization = "Authorization: Bearer " . $apiKey;

print($data_end_device."\n");
$ch1 = curl_init($url1);
curl_setopt($ch1, CURLOPT_HTTPHEADER, array($authorization, 'Content-Type: application/json'));
curl_setopt($ch1, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch1, CURLOPT_POSTFIELDS, $data_end_device);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch1, CURLOPT_FOLLOWLOCATION, 1);
$result1 = curl_exec($ch1);
curl_close($ch1);
print($result1."\n\n\n");
                
print($data_join_server."\n");  
$ch2 = curl_init($url2);
curl_setopt($ch2, CURLOPT_HTTPHEADER, array($authorization, 'Content-Type: application/json'));
curl_setopt($ch2, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch2, CURLOPT_POSTFIELDS, $data_join_server);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_FOLLOWLOCATION, 1);
$result2 = curl_exec($ch2);
curl_close($ch2);
print($result2."\n\n\n");   

print($data_network_server."\n");                
$ch3 = curl_init($url3);
curl_setopt($ch3, CURLOPT_HTTPHEADER, array($authorization, 'Content-Type: application/json'));
curl_setopt($ch3, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch3, CURLOPT_POSTFIELDS, $data_network_server);
curl_setopt($ch3, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch3, CURLOPT_FOLLOWLOCATION, 1);
$result3 = curl_exec($ch3);
curl_close($ch3);
print($result3."\n\n\n");

print($data_application_server."\n");  
$ch4 = curl_init($url4);
curl_setopt($ch4, CURLOPT_HTTPHEADER, array($authorization, 'Content-Type: application/json'));
curl_setopt($ch4, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch4, CURLOPT_POSTFIELDS, $data_application_server);
curl_setopt($ch4, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch4, CURLOPT_FOLLOWLOCATION, 1);
$result4 = curl_exec($ch4);
curl_close($ch4);
print($result4."\n\n\n");

Will do some more tidying up and put this in to a repro

Many Many Thanks :innocent: :innocent:
I will also share my code once it is up and runing.

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.