Skip to content

TheThingsNetwork/lorawan-devices

Repository files navigation

Device Repository for LoRaWAN®

The Device Repository contains information about LoRaWAN end devices. The Device Repository acts as key data source for device catalogs and onboarding devices on LoRaWAN networks.

We welcome device makers to contribute information to help users find and onboard end devices in products and services developed and offered by The Things Industries, including The Things Stack.

Database Protection Right

The contents of this Device Repository is obtained, verified and structured by The Things Industries B.V. and The Things Network Foundation. As such, the Device Repository is a database protected by copyright and sui generis right as defined by the Database Directive (Directive 96/9/EC of the European Parliament and of the Council). You may not extract and/or reuse the Device Repository as a whole or a substantial part of its content. You are, however, permitted to reuse or extract information about an individual end device.

Example

Curious to how end devices, profiles and payload is defined in the Device Repository? Go to the fully documented example.

How-to video

To help you add devices to this repository, you can follow along in this example video where we walk through all of the instructions below.

Adding devices to the device repository

Prerequisites

One of the operating systems:

Development dependencies:

  • Node.js version 16.x
    • (This is recommended, as newer versions may give errors)
  • npm version 8.x
  • Go version 1.18.x

To check your Node.js, npm and Go versions:

$ node -v
$ npm -v
$ go version

Download and install Node.js and npm and Download Go.

Then, install the dependencies:

$ make deps

Contributing

If you want to submit your devices to the Device Repository, fork this repository and open a pull request. Learn how to fork and create pull requests.

Pull requests are validated automatically. If there are any validation or formatting errors, the validation checks will not pass, and the pull request will not be merged until those errors are resolved. Therefore, before creating a pull request, run the following action to validate and format your data locally:

$ make validate fmt

Contributors are required to sign the Contributor License Agreement.

Validation

The Device Repository contains tooling to validate all data against a schema. This is necessary for all data to be loaded automatically in The Things Stack and other services.

To validate data:

$ make validate

The validation also supports validating a single vendor's files:

$ make validate VENDOR_ID=<id-of-vendor>

Visual Studio Code is a great editor for editing the Device Repository. You can validate your data automatically using the YAML plugin.

The YAML plugin supports you with filling out the document. When hitting Ctrl + Space, all fields are shown. The Debug Console of Visual Studio provides feedback by highlighting the incorrect fields.

Validation in Visual Studio Code

To use the YAML plugin correctly, you need to assign the schema to the plugin. To do this, open the command palette (Shift+Command+P on Mac or Ctrl+Shift+P for Windows/Linux) and search for Preferences: Open Workspace Settings (JSON). Then add the following lines:

{
  // other settings go here

  "yaml.schemas": {
          "https://schema.thethings.network/devicerepository/1/schema": "vendor/**/*.yaml"
  }
}

Files and Directories

There are six file types in the Device Repository:

  1. Vendor index with a list of vendors (vendor/index.yaml)
  2. Vendor device index with all the devices of a vendor (vendor/<vendor-id>/index.yaml)
  3. End device definition of a single device (vendor/<vendor-id>/<device-id>.yaml)
  4. End device profile for one or more devices (vendor/<vendor-id>/<profile-id>.yaml). Note: this can also refer to a profile in a different vendor folder, by specifying the vendorID. See below for an example
  5. Payload codec definition for one or more devices (vendor/<vendor-id>/<codec>.yaml)
  6. Payload codec implementation to decode and encode payload (vendor/<vendor-id>/<codec>.js)

All files and folders must have lowercase titles.

An example directory structure with a vendor named company-x that produces two devices (device-a and device-b). There's a module maker named module-maker that provides a standard profile module-profile-eu868 that can be referenced by end device vendors:

lorawan-devices
├── vendor
│   ├── index.yaml                    # vendor index (1)
│   ├── module-maker
│   │   └── module-profile-eu868.yaml # generic end device profile for EU868 (4)
│   ├── company-x
│   │   ├── index.yaml                # vendor device index (2)
│   │   ├── logo.svg                  # vendor logo
│   │   ├── device-a.png              # photo of device-a
│   │   ├── device-a.yaml             # device-a definition (3)
│   │   ├── device-b.png              # photo of device-b
│   │   ├── device-b.yaml             # device-b definition (3)
│   │   ├── custom-profile-us915.yaml # end device profile for US915 (4)
│   │   ├── codec.js                  # payload codec implementation (6)
│   │   └── codec.yaml                # payload codec definition (5)

Vendor Index

First, make sure that your company is listed in the Vendor index in vendor/index.yaml and that the information is complete.

If your company is not listed or if you want to add additional information, add your information like so:

vendors:
  - # Unique identifier of the vendor (lowercase, alphanumeric with dashes, max 36 characters)
    id: company-x
    # Vendor company name
    name: Company X
    # Vendor company description (optional)
    description:
    # LoRa Alliance issued Vendor ID
    vendorID: 10
    # Vendor website (optional)
    website: https://www.company-x.com
    # Vendor logo filename (optional)
    logo: logo.svg
    # Vendor social media links and handles (optional)
    social:
      linkedin: https://www.linkedin.com/company/company-x/ # uri
      facebook: https://www.facebook.com/company-x # uri
      twitter: company-x  # handle
      instagram: company-x # handle
      github: company-x # handle
    # Organization Unique Identifiers (OUIs, six digit hex, optional): http://standards-oui.ieee.org/oui.txt
    # The OUI is typically the first 3 bytes of the DevEUI
    ouis:
      - FCD6BD
    # Private Enterprise Number (optional): https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers
    pen: 42

The vendor data will be in the vendor/<vendor-id> folder (e.g. vendor/company-x). Create the folder if it does not exist yet.

Vendor Device Index

All vendor data is referenced from the Vendor device index file: vendor/<vendor-id>/index.yaml:

endDevices:
  - device-a
  - device-b
# The profileIDs is a distinct value for every unique profile listed in the vendor's folder.
# This value can be freely issued by the vendor and is also used on the QR code for LoRaWAN devices, see
# https://lora-alliance.org/wp-content/uploads/2020/11/TR005_LoRaWAN_Device_Identification_QR_Codes.pdf#page=8
# It can either be a combo of device ID + hardware version + firmware version + region, or profile ID + codec ID
# NOTE: The profileIDs is different from the vendorID.
profileIDs:
  '1':
    endDeviceID: 'device-a'
    firmwareVersion: '1.0'
    hardwareVersion: '1.0'
    region: 'EU863-870'
  '2':
    id: 'device-b-profile-915' # Name of the file of the profile 
    codec: 'device-b-codec' # Name of the yaml file of the codec

All end device identifiers must be lowercase, alphanumeric with dashes and max 36 characters. Make sure you include every device you add.

End Device

For each end device, create an End device definition file with the same filename as the identifier in the index: vendor/<vendor-id>/<device-id>.yaml:

name: Device A # Device name can not contain the vendor name
description: My first LoRaWAN device
# Hardware versions (optional)
hardwareVersions:
  - version: '1.0'
    numeric: 1
# Firmware versions (at least one is mandatory)
firmwareVersions:
  - # Firmware version
    version: '1.0'
    numeric: 1
    # Supported hardware versions (optional)
    hardwareVersions:
      - '1.0' # Must refer to hardwareVersions declared above
    # LoRaWAN Device Profiles per region
    # Supported regions: EU863-870, US902-928, AU915-928, AS923, CN779-787, EU433, CN470-510, KR920-923, IN865-867, RU864-870
    profiles:
      EU863-870:
        # Optional identifier of the vendor of the profile. When you specify the vendorID, the profile is loaded from
        # the vendorID's folder. This allows you to reuse profiles from module or LoRaWAN end device stack vendors.
        # When vendorID is empty, the profile is loaded from the current directory.
        vendorID: module-maker
        # Unique identifier of the profile (lowercase, alphanumeric with dashes, max 36 characters).
        # This is the file name of the profile and must have the .yaml extension.
        id: module-profile-eu868
        # Specify whether the device is LoRa Alliance certified.
        lorawanCertified: true
        codec: device-a-codec
      US902-928:
        # This is the file name of the profile and must have the .yaml extension.
        id: custom-profile-us915
        # Specify whether the device is LoRa Alliance certified.
        lorawanCertified: true
        # This is the file name of the codec defintion and must have the .yaml extension.
        codec: device-a-codec

There are many other fields that can be set: hardware versions, firmware versions, sensors, dimensions, weight, battery information, operating conditions, IP code, security information, photos and regulatory and compliancy information. See Example Wind Sensor for a full example.

NOTE It is highly recommended to fill out as many information about the end devices as possible. The definition above is the bare minimum information.

End Device Image

There are a few guidelines to follow for images:

  • At least 1 image of each device you intent to add.
  • Make sure the image has a transparent background.
  • Image should be of high quality.
  • The image cannot be bigger then 2000 x 2000 pixels.

End Device Profile

Each referenced end device profile needs to be defined in the End device profile, with the same filename as the profile ID: vendor/<vendor-id>/<profile-id>.yaml:

# LoRaWAN MAC version: 1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 or 1.1
macVersion: '1.0.3'
# LoRaWAN Regional Parameters version. Values depend on the LoRaWAN version:
#   1.0:   TS001-1.0
#   1.0.1: TS001-1.0.1
#   1.0.2: RP001-1.0.2 or RP001-1.0.2-RevB
#   1.0.3: RP001-1.0.3-RevA
#   1.0.4: RP002-1.0.0, RP002-1.0.1, RP002-1.0.2, RP002-1.0.3 or RP002-1.0.4
#   1.1:   RP001-1.1-RevA or RP001-1.1-RevB
regionalParametersVersion: 'RP001-1.0.3-RevA'

# Whether the end device supports join (OTAA) or not (ABP)
supportsJoin: true
# If your device is an ABP device (supportsJoin is false), uncomment the following fields:
# RX1 delay
#rx1Delay: 5
# RX1 data rate offset
#rx1DataRateOffset: 0
# RX2 data rate index
#rx2DataRateIndex: 0
# RX2 frequency (MHz)
#rx2Frequency: 869.525
# Factory preset frequencies (MHz)
#factoryPresetFrequencies: [868.1, 868.3, 868.5, 867.1, 867.3, 867.5, 867.7, 867.9]

# Maximum EIRP
maxEIRP: 16
# Whether the end device supports 32-bit frame counters
supports32bitFCnt: true

# Whether the end device supports class B
supportsClassB: false
# If your device supports class B, uncomment the following fields:
# Maximum delay for the end device to answer a MAC request or confirmed downlink frame (seconds)
#classBTimeout: 60
# Ping slot period (seconds)
#pingSlotPeriod: 128
# Ping slot data rate index
#pingSlotDataRateIndex: 0
# Ping slot frequency (MHz). Set to 0 if the band supports ping slot frequency hopping.
#pingSlotFrequency: 869.525

# Whether the end device supports class C
supportsClassC: false
# If your device supports class C, uncomment the following fields:
# Maximum delay for the end device to answer a MAC request or confirmed downlink frame (seconds)
#classCTimeout: 60

For more information and for fields for ABP, see LoRaWAN Schema: Devices Draft 1.

Payload Codecs

The Device Repository supports three payload codecs to be defined:

  1. Uplink decoder: decodes binary data uplink into a JSON object
  2. Downlink encoder: decodes a JSON object into binary data downlink
  3. Downlink decoder: decodes an encoded binary data downlink back into a JSON object (must be symmetric with the downlink encoder)

Note: We recommend using measure units and full variable names in payload decoders for a better user experience.

The codecs can all be defined in one file as they are defined by their function names. The codecs must be written in JavaScript (ECMAScript 5.1+). See link for instructions on how to write decoders and encoders.

The codecs are defined in the Payload codec definition file, with the same filename as the codec ID: vendor/<vendor-id>/<codec>.yaml:

# Uplink decoder decodes binary data uplink into a JSON object (optional)
# For documentation on writing encoders and decoders, see: https://thethingsstack.io/integrations/payload-formatters/javascript/
uplinkDecoder:
  fileName: codec.js
  # Examples (optional)
  examples:
    - description: 32 knots from the North
      input:
        fPort: 1
        bytes: [0, 32]
      output:
        data:
          direction: 'N'
          speed: 32
      # Normalized output, uses the normalizeUplink function (optional)
      normalizedOutput:
        data:
          - wind:
              speed: 16.4608
              direction: 0
# Downlink encoder encodes JSON object into a binary data downlink (optional)
downlinkEncoder:
  fileName: codec.js
  # Examples (optional)
  examples:
    - description: Turn green
      input:
        data:
          led: green
      output:
        bytes: [1]
        fPort: 2
# Downlink decoder decodes the encoded downlink message (optional, must be symmetric with downlinkEncoder)
downlinkDecoder:
  fileName: codec.js
  # Examples (optional)
  examples:
    - description: Turn green
      input:
        fPort: 2
        bytes: [1]
      output:
        data:
          led: green

The actual Payload codec implementation is in the referenced filename: vendor/<vendor-id>/<codec-filename>.

See The Things Stack documentation for how to write JavaScript functions for decoding, normalizing and encoding data.

Legal

Copyright © 2020-2022 The Things Industries B.V.

All product names, logos, and brands are property of their respective owners. All company, product and service names used in the Device Repository are for identification purposes only. Use of these names, logos, and brands does not imply endorsement.