LoRa Device Management Documentation
Introduction
The LoRa API helps you to manage your LoRaWAN devices and application servers.
KPN’s Low Power Long Range (LoRa) network service complements existing 2G, 3G, 4G and LTE-M networks. It is based on the LoRaWAN protocol for Internet of Things (IoT). The network eliminates significant barriers (such as cost and energy consumption) so that numerous (battery-powered) devices can be connected.
KPN has equipped hundreds of existing mobile transmission towers across the Netherlands with a LoRaWAN gateway and antenna, achieving full coverage of the Netherlands and allowing millions of devices to be connected.
API specification
Base URL
https://api-prd.kpn.com/data/lora/thingpark
Conceptual model
Definitions
ABP
Activation by personalization. In some cases, you might need to hard code the device address (DevAddr
) as well as the security keys in the device.
ABP provisioning is no longer supported and not available in the API. Over-the-Air Activation (OTAA) is the standard.
Application routing profile
Configuration data in the LoRa network referencing the application server of the customer.
Application server
LoRa application server of the customer which is able to receive LoRa uplinks and initiate LoRa downlinks.
Device
A sensor or actuator implementing the LoRaWAN protocol stack. A device is identified by DevEUI, a globally unique IEEE EUI-64 identifier.
DevEUI
The DevEUI is a 64-bit globally-unique Extended Unique Identifier (EUI-64) assigned by the manufacturer, or the owner, of the end-device.
Device alarm
An occurrence out of the ordinary on a device logged by the LoRa network.
HSM group
HSM (High-Security Module). The data in the LoRa platform is protected by an HSM which stores root-keys for the encryption of the device-data. Within the platform, there may be multiple groups of HSMs, but currently only 1 group is present.
The HSM is mandatory for LoRa provisioning by default. If you are not using a HSM, the Legacy interface version 1.1.1 must be used. You can do this by adding following http-header to the request: api-version: v1.1.1
OTAA
Over-the-Air Activation. Devices perform a join-procedure with the network, during which a dynamic device address (DevAddr
) is assigned and security keys are negotiated with the device.
Thingpark GUI
The Thingpark GUI by Actility allows you manage your devices in an web GUI. You can also see the LoRa messages sent and received by their devices. You need you Thingpark credentials to use this API.
API workflows
Activate the LoRa API
After you created a project in the KPN Developer Portal we have to match your Thingpark GUI user credentials with your KPN Developer Portal user credentials. We call that 'activation'. You have to do it just once. After that, you can use the project by sending your requests with you KPN Developer Portal access token.
You have to activate each new project because it has a new set of
client_id
andclient_secret
.
Retrieve LoRa subscription information
Before you provision a device or application routing profile, you can retrieve the available resources in the subscription:
- Connectivity plans: The available connectivity options provided by sales. Includes the number of messages per day and localization feature(s).
- Device profiles: Indicates the type of device. Typically used to optimize the motion indication (is it a static device or is it expected to be moving).
- HSM groups: Indication of available HSMs to be used. Currently, there is only 1 option. The hsmGroupId is needed while creating devices and application routing profiles.
LoRa application routing profile management
The application routing profile is used to configure the application server endpoint and is used and referenced by the LoRa device management in the next section. You will need at least 1 application routing profile pointing to your application server to be able to start creating devices.
LoRa device management
This workflow provisions the LoRa device into the KPN network. Before you can create a new device you need to know 3 important parameters:
Parameter | Description |
---|---|
Device EUI (DevEUI) |
Globally unique IEEE EUI-64 device identifier. |
Application EUI (AppEUI) |
Globally unique IEEE-64 identifying the LoraWAN join server. |
Application Key (AppKey) |
Root key of the device (16 bytes). The Application Key can only be used while creating a device and cannot be updated or retrieved due to security constraints. |
LoRa device alarm management
You can retrieve and acknowledge device alarms by using this workflow.
Retrieve LoRa statistics
This workflow retrieves the frame (traffic) statistics and health statistics of the device(s).
Features
- LoRaWan application services mangement.
- LoRa device management.
- LoRa application routing profile management.
- LoRa device alarm management.
- LoRa statistics retrieval.
Getting started
Make sure you've read What's in it for you for more info on how to register and start testing APIs.
Authentication
The API follows the KPN Store API Authentication Standard to secure the API. It includes the use of OAuth 2.0 client_id
and client_secret
to receive an access token.
Go to the Authentication tab on top of this page to find out how to:
- Authenticate to an API using cURL.
- Authenticate to an API on Swaggerhub.
- Import Open API Specifications (OAS), also called Swagger files into Postman.
How to...
Activate the LoRa API
The following endpoint activates the LoRa API: POST /activate
.
Send your Thingpark GUI user credentials in the body of the request to authorize the Developer Portal to make use of your LoRa instance for future LoRa API requests.
cURL request
{
POST 'https://api-prd.kpn.com/data/lora/thingpark/activate' \
--header 'Authorization: Bearer **' \
--header 'Content-Type: application/json' \
--data-raw '{
"thingpark_username":"**",
"thingpark_password":"**"
}
Body parameters
Parameter | Type | Description |
---|---|---|
thingpark_username |
string |
Your Thingpark GUI username. |
thingpark_password |
string |
Your Thingpark GUI password. |
Response
The expected response is 200 OK
.
Retrieve LoRa subscription information
The following request retrieves a list of connectivity plans: GET /connectivityPlans
.
Response example
[
{
"id": "kpn-acc-ope-cs/testing",
"ref": "608",
"name": "kpn-acc-ope Testing CP",
"grantedConnections": 10,
"usedConnections": 1,
"communicationType": "UNICAST"
},
{
"id": "kpn-acc-ope-cs/often-geo-2019",
"ref": "624",
"name": "Often Geo 2019eb",
"grantedConnections": 100000,
"usedConnections": 0,
"communicationType": "UNICAST"
}
]
Parameter | Type | Description |
---|---|---|
id |
string |
ID of the connectivity plan. |
ref |
string |
Reference of the connectivity plan. |
name |
string |
Name of the connectivity plan. |
grantedConnections |
integer |
Number of granted connections of the connectivity plan. |
usedConnections |
integer |
Number of used connections of the connectivity plan. |
communicationType |
string |
Communication type of connectivity plan: UNICAST , MULTICAST . |
Create an application routing profile
The following request creates a new routing profile: POST /routingProfiles
.
POST /routingProfiles
{
"name": "your-routing-profile-name",
"default": false,
"hsmGroupId": "HSM_KPN-OPE.1",
"rsaPublicKey": "-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn0/KaJwVk7lyRMsGUKiYtnMp4kwo45+eaFB9NnYeZe/I5wnwQKC6goN9C1xQy38alc/rMyUbrhsyUmfYfZTPXSuMtveXS15KR2vZW+MGOeA9Bpr2X/N4dUyPTG6fpEAnIwSCeOor40oVXPPvl4bbOV1EdGm5QXWArl9nUDqmIzu0XzcM/VQVyhT7rHuAcIigXpNeUzGOBLmLFjuEqG2r/3VRW147L1tWr8mogyDv4uV+uHckD4ceIMds7jk9AgwVi4JdZv6nMg2wGX0IaVAnTghjgVmsU5k2azf01U0AWYHbwnEsnixnQhW4Rx71NmiKU2Fflhl/g5e8+ZjZhvCN7QIDAQAB-----END PUBLIC KEY-----",
"routes": [
{
"sourcePorts": "*",
"strategy": "SEQUENTIAL",
"contentType": "JSON",
"asId": "YOUR-AS-ID",
"asKey": "6dd70c8511e02ac833add9a146f5bf23",
"addresses": [
"https://your-application-server/path/"
]
}
]
}
Parameter | Type | Description |
---|---|---|
name |
string |
Name of the routing profile. |
default |
boolean |
Indicates if the routing profile should be used by default for new devices. |
hsmGroupId |
string |
HSM group ID which can be found from the retrieval of subscription data. |
rsaPublicKey |
integer |
Public key from the application server used to encrypt the Application Server Key (ASK). |
connectivityPlanId |
integer |
Connectivity plan ID which can be found from the retrieval of subscription data. |
asId |
string |
Application server identifier, used for authentication. |
asKey |
string |
Application server password, used for authentication (16 byte hexadecimal). |
addresses |
string |
List of HTTPS endpoint destination(s) of the application server. |
The response will echo the settings and includes some extra parameters:
Parameter | Type | Description |
---|---|---|
id |
string |
Identification in the LoRa network. |
ref |
boolean |
API reference for future requests (update/delete/retrieve). |
rsaEncryptedASKey |
string |
Application Server Key (ASK) encrypted with the public key in the request. The ASK is needed to encrypt/decrypt the LoRa payload by the application server. This field will be returned only once and cannot be retrieved from the platform after this call. Please store and protect this value well. |
Response example
{
"id": "TWA_100001135.2647",
"ref": "2647",
"name": "your-routing-profile-name",
"default": false,
"rsaEncryptedASKey": "8e4bda2fda868e536a821ee8930e8ceb3baaa22ea9588c5b220d61acf8678740496923c537aa551bdf13af815bbabb31ce66d3248b9489b7e19cc778b8aac787578b079778722c67908296d157ad21a1bb99eada4f7db48fd51a5276aecc621638d9c7aed50347e7546a13a07d97557413e8505f32d57edb2caaf63849558d01ad60c0c617bb6dcb4cd40e3b3ccff6bf2c50442c539337de01808725ac535ab3dccb77fe635015060984270bbe3d356644a7e8a6574fd726e165818ffb507b8ddfbbe9ce25692cbb69efeb0b024cd45d08e66f0d284bcbac1c56fe95744f3bae89920709ef27d19444f6559de16290da67e67ff85564c8f0cde9c3c4979608be",
"routes": [
{
"sourcePorts": "*",
"strategy": "SEQUENTIAL",
"contentType": "JSON",
"asId": "YOUR-AS-ID",
"addresses": [
"https://your-application-server/path/"
]
}
]
}
Create a device
The following request creates a new device: POST /devices
.
Please note:
- New devices should be provisioned as Over-the-Air Activation (
activationType
=OTAA
). - New devices should use HSM security (
hsmGroupId
field must contain a valid value). - If no
routingProfileId
orprocessingStrategyId
values are provided, thenprocessingStrategyId
will be automatically set toDATAFLOW
. - If no
connectivityPlanId
value is provided, then the first connectivity plan of the subscriber with available connections will be assigned to the device.
POST /devices
{
"name": "Test Device via API",
"EUI": "0059ac0000170311",
"activationType": "OTAA",
"deviceProfileId": "CUSTOM/Static V 1.0 Class A",
"hsmGroupId": "HSM_KPN-ACC-OPE.1",
"connectivityPlanId": "kpn-acc-ope-cs/often-geo-2019",
"routingProfileId": "TWA_100001135.861",
"applicationEUI": "0000000000000000",
"applicationKey": "00000000000000000000000000000000"
}
Parameter | Type | Description |
---|---|---|
name |
string |
Name of the device. |
EUI |
string |
Device EUI identification (8 bytes hexadecimal). |
activationType |
string |
Fixed value OTAA for Over-the-Air Activation. |
hsmGroupId |
string |
HSM group ID, which can be found from the retrieval of subscription data. Required . |
deviceProfileId |
string |
Device profile ID, which can be found from the retrieval of subscription data. |
connectivityPlanId |
string |
Connectivity plan ID which can be found from the retrieval of subscription data. |
routingProfileId |
string |
Routing profile ID of the application server. |
applicationEUI |
string |
AppEUI identifying the LoRaWAN join server (8 bytes hexadecimal). |
applicationKey |
string |
Device root key (16 bytes hexadecimal). |
The response will echo the settings and includes an extra parameter:
ref
: API reference for future requests (update/delete/retrieve).
Response example
{
"ref": "15532",
"name": "Test device",
"EUI": "0059ba0000000002",
"activationType": "OTAA",
"deviceProfileId": "CUSTOM/Static V 1.0 Class A",
"connectivityPlanId": "kpn-acc-ope-cs/often-geo-2019",
"routingProfileId": "TWA_100001135.2647",
"applicationEUI": "01234567890abcdef",
"hsmGroupId": "HSM_KPN-OPE.1"
}
Delete a device
The following request deletes a device: DELETE /devices/{deviceRef}
.
You have to pass the ref
parameter in the path of the request:
- Use the
ref
parameter that you saved when the device was created. - Use the
GET
method to retrieve theref
parameter again:GET /devices/{deviceRef}
Example path parameters
Parameter | Type | Description |
---|---|---|
deviceRef |
string (path) |
Reference of the device to be deleted. |
Retrieve LoRa device alarms
The following request retrieves a list of device alarms:
GET /deviceAlarms
Example request parameter
Parameter | Type | Description |
---|---|---|
deviceEUI |
string (query) |
EUI of the device to search alarms for. |
Response example
[
{
"ref": "5a6717531ffbe425b9c16bb6",
"alarmState": "MAJOR",
"occurrence": 1,
"acked": false,
"creationTime": "2018-01-23T11:06:59.073+00:00",
"lastUpdateTime": "2018-01-23T11:06:59.073+00:00",
"additionalInfo1": "SF12",
"additionalInfo2": "SF10",
"additionalInfo3": "13.000000dB",
"additionalInfo4": "-15.000000dB",
"deviceRef": "41201",
"deviceAlarmTypeId": 6
},
{
"ref": "5a6847972d3694372cad4fed",
"alarmState": "WARNING",
"occurrence": 9,
"acked": false,
"creationTime": "2018-01-24T08:45:11.742+00:00",
"lastUpdateTime": "2018-02-04T08:52:05.384+00:00",
"additionalInfo1": "20%",
"deviceRef": "32611",
"deviceAlarmTypeId": 1
}
]
Parameter | Type | Description |
---|---|---|
ref |
string |
Reference of the alarm. |
alarmState |
string |
State of the alarm. Possible values are, by ascending order of criticality: CLEARED , UNCLEARED , WARNING , MINOR , MAJOR and CRITICAL . |
occurrence |
integer($int32) |
Number of occurrences of the alarm. |
acked |
boolean |
Indicates if the alarm has been acknowledged. |
creationTime |
string |
ISO 8601 time of the alarm creation. |
lastUpdateTime |
string |
ISO 8601 time of the last alarm acknowledgement. |
additionalInfo1 |
string |
First additional information related to the alarm creation. Note: There can be more than 1 additional info. |
deviceRef |
string |
Reference of the device related to the alarm. |
deviceAlarmTypeId |
string |
ID of the device alarm type. Refer to the list of ThingPark device alarm types to get the corresponding label. |
Retrieve LoRa statistics
Get frame statistics for a device
The following request retrieves frame statistics of the devices corresponding to the provided parameters:
GET /deviceFrameStatistics
You have to pass certain parameters in the path of the request. See below:
Example path parameters
Parameter | Type | Description |
---|---|---|
deviceEUIList |
string |
List of device EUIs for which device statistics should be retrieved. |
baseStationId |
string |
ID of the base station which received the frame. |
startDate |
string |
Start date in ISO 8601 format of the period for which frame statistics should be retrieved. By default, only the last frame statistics resource is retrieved. |
duration |
integer($int32) |
Period (number of days) for which frame statistics should be retrieved. By default, the default duration is 7 days. |
aggregationStep |
integer($int32) |
Number of hours (between 1 and 24) used for aggregating the frame statistics. By default, all frame statistics are returned (no aggregation). |
Response example
[
{
"type": "UPLINK",
"date": "2020-01-31T13:00:00.000+00:00",
"frameCount": 2,
"payloadSize": 2,
"baseStationRSSI": -38.2,
"baseStationSNR": 2.6,
"payloadReceivedOnTime": 2,
"payloadReceivedLate": 0,
"payloadReceivedOnTimeSize": 2,
"payloadReceivedLateSize": 0,
"averagePER": 0.0
},
{
"type": "DOWNLINK",
"date": "2020-01-31T13:00:00.000+00:00",
"frameCount": 3,
"payloadSize": 0,
"payloadSentWithSuccess": 3,
"payloadSentWithSuccessSize": 0,
"payloadSentWithFailure": 0,
"payloadSentWithFailureSize": 0
}
]
Parameter | Type | Description |
---|---|---|
type |
string |
Type of frame. Possible values are UPLINK or DOWNLINK . |
date |
string |
SISO 8601 time of the frame emission/reception or time of the aggregated time slot. |
frameCount |
integer($int32) |
Number of uplink/downlink frames received or sent for this aggregated time slot. |
payloadSize |
integer($int32) |
Size of the frame payload or average size of payload associated to this aggregated time slot. |
baseStationRSSI |
number |
Received Signal Strength Indication (RSSI) for the base station that receives the frame. Only available in case of an uplink. |
baseStationSNR |
number |
Signal Noise Ratio (SNR) Indication for the base station that receives the frame. |
payloadReceivedOnTime |
integer($int32) |
Number of uplinks sent with no delay by the base station. Only available in case of an uplink. |
payloadReceivedLate |
integer($int32) |
Number of uplinks queued in the base station and sent with a delay. Only available in case of an uplink. |
payloadReceivedOnTimeSize |
integer($int32) |
Size of the accumulated uplink payloads sent with no delay by the base station. Only available in case of an uplink. |
payloadReceivedLateSize |
integer($int32) |
Size of the accumulated uplink payloads queued in the base station and sent with a delay. Only available in case of an uplink. |
Get health statistics for a device
The following request retrieves health statistics for all devices: GET /deviceHealthStatistics
.
Response example
{
"initCount": 11,
"activeCount": 55,
"rfConnectionErrorCount": 0,
"totalCount": 66
}
Parameter | Type | Description |
---|---|---|
initCount |
integer($int32) |
Number of devices with the healthState attribute set to INIT . |
activeCount |
integer($int32) |
Number of devices with the healthState attribute set to ACTIVE . |
rfConnectionErrorCount |
integer($int32) |
Number of devices with the healthState attribute set to RF_CNX_ERROR . |
totalCount |
integer($int32) |
Total number of devices in authorized scopes. |
Application status message
The 4XX and 5XX status messages may contain additional application layer information. The Response may include an errorId
field which can be used for detailed analysis. The latest known errors are listed below under 'Error ID codes'.
Error response example
{
"code": 400,
"message": "Bad request: No ConnectivityPlan for ID: kpn-acc-ope-cs/often-geo-1919 and Operator: 24",
"errorId": "OSS-214"
}