Skip to content

Commit

Permalink
Validate features (#736)
Browse files Browse the repository at this point in the history
* check vendor present in index

* validate single vendor

* add vendorprofileid check

* update PULL_REQUEST_TEMPLATE

* remove some vendorprofileID checks

* clearer error and prettier

* update all profileVendorID to be unique per vendor

* improve vendorProfileID explanation further

* validate specific vendor README update

* Add pre-commit hook for validation

* run validate and fmt

* update nexelec vendorprofileid

* install pre-commit hooks with make deps

* add feedback

* Revert update all profileVendorID to be unique per vendor

This reverts commit 1a4ac1a.

* Revert update nexelec vendorprofileid

* update all vendorProfileID

* update vendor-id to VENDOR_ID

* fix vendor_id again

* remove duplicate index check

* remove vendorProfileID and add profileIDs

* validate

* add all hardwareVersion & update schema

* delete temp script

* fixes and update

* update ks-technologies

* update README & example

* Add vendorProfileID deprecation message

* fix profileIDs

* update profileID

* fix vendor in index

---------

Co-authored-by: Johan Stokking <[email protected]>
Co-authored-by: Jaime Trinidad <[email protected]>
  • Loading branch information
3 people authored Apr 11, 2024
1 parent 5aedc12 commit 3a8dc15
Show file tree
Hide file tree
Showing 705 changed files with 887 additions and 2,361 deletions.
4 changes: 2 additions & 2 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ Closes #0000, References #0000, etc.
- ...

#### Checklist for Reviewers
<!-- Guidelines to follow when reviewing pull request -->
<!-- Guidelines to follow when reviewing pull request, please do not remove. -->

- [ ] Title and description should be descriptive (Not just a serial number for example).
- [ ] `vendorProfileID` should not be `vendorID`.
- [ ] `profileIDs` should not be `vendorID` and should be a unique value for every profile.
- [ ] All devices should be listed in the vendor's `index.yaml` file.
- [ ] At least 1 image per device and should be transparent.

Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ GO = go
GOBIN = $(PWD)/bin
export GOBIN

VENDOR_ID=

.PHONY: default
default: validate

Expand All @@ -28,14 +30,15 @@ deps:
$(NPM) install
pushd ./tools/runscript && $(GO) install . && popd
pushd ./tools/validate-image && $(GO) install . && popd
$(NPM) run install-hooks

.PHONY: deps.update
deps.update:
$(GIT) subtree pull -P lib/draft https://github.com/lorawan-schema/draft-devices.git v1

.PHONY: validate
validate:
$(NPM) run validate
@if [ -z "${VENDOR_ID}" ]; then $(NPM) run validate; else $(NPM) run validate -- --vendor-id $(VENDOR_ID); fi

.PHONY: fmt
fmt:
Expand Down
26 changes: 20 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ To validate data:
$ make validate
```

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

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

[Visual Studio Code](https://code.visualstudio.com/) is a great editor for editing the Device Repository. You can validate your data automatically using the [YAML plugin](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml).

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.
Expand Down Expand Up @@ -155,6 +161,20 @@ All vendor data is referenced from the **Vendor device index** file: `vendor/<ve
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.**
Expand Down Expand Up @@ -218,12 +238,6 @@ There are a few guidelines to follow for images:
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`:

```yaml
# Vendor profile ID, can be freely issued by the vendor. NOTE: The vendor profile ID is different from the vendorID.
# The vendor Profile ID should be an incremental counter for every unique device listed in the vendor's folder.
# This vendor profile ID 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
vendorProfileID: 0
# 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:
Expand Down
4 changes: 4 additions & 0 deletions bin/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

set -e
make validate fmt
62 changes: 55 additions & 7 deletions bin/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,19 @@ const imageType = require('image-type');

const ajv = new Ajv({ schemas: [require('../lib/payload.json'), require('../schema.json')] });

const options = yargs.usage('Usage: --vendor <file>').option('v', {
alias: 'vendor',
describe: 'Path to vendor index file',
type: 'string',
demandOption: true,
default: './vendor/index.yaml',
}).argv;
const options = yargs
.usage('Usage: --vendor <file> [--vendor-id <id>]')
.option('v', {
alias: 'vendor',
describe: 'Path to vendor index file',
type: 'string',
demandOption: true,
default: './vendor/index.yaml',
})
.option('vendor-id', {
describe: 'Specific vendor ID to validate',
type: 'string',
}).argv;

let validateVendorsIndex = ajv.compile({
$ref: 'https://schema.thethings.network/devicerepository/1/schema#/definitions/vendorsIndex',
Expand Down Expand Up @@ -205,6 +211,30 @@ function formatValidationErrors(errors) {

const vendors = yaml.load(fs.readFileSync(options.vendor));

// Get the list of vendor IDs from the vendor/index.yaml
const vendorIds = vendors.vendors.map((vendor) => vendor.id);

// Get the list of vendor folders in the vendor directory
const vendorFolders = fs
.readdirSync('./vendor', { withFileTypes: true })
.filter((dirent) => dirent.isDirectory())
.map((dirent) => dirent.name);

// Check for vendor folders that are not listed in the vendor/index.yaml
const vendorsNotInIndex = vendorFolders.filter((folderName) => !vendorIds.includes(folderName));

if (vendorsNotInIndex.length > 0) {
console.error(
`Vendors found in the 'vendor' folder that are not listed in ${options.vendor} index:\n${vendorsNotInIndex.join(
', '
)}`
);
process.exit(1);
} else {
console.log(`All vendors in the 'vendor' folder are listed in ${options.vendor} index.`);
}

// Validate vendors index
if (!validateVendorsIndex(vendors)) {
console.error(`${options.vendor} index is invalid: ${formatValidationErrors(validateVendorsIndex.errors)}`);
process.exit(1);
Expand All @@ -213,7 +243,18 @@ console.log(`vendor index: valid`);

const vendorProfiles = {};

const vendorIDToValidate = options['vendor-id'];

if (vendorIDToValidate && !vendors.vendors.some((v) => v.id === vendorIDToValidate)) {
console.error(`Specified vendor ID '${vendorIDToValidate}' does not exist in the repository.`);
process.exit(1);
}

vendors.vendors.forEach((v) => {
if (vendorIDToValidate && v.id !== vendorIDToValidate) {
return;
}

const key = v.id;
const folder = `./vendor/${v.id}`;

Expand Down Expand Up @@ -294,11 +335,18 @@ vendors.vendors.forEach((v) => {
const regionProfile = version.profiles[region];
const key = `${v.id}: ${d}: ${version.version}: ${region}`;
const vendorID = regionProfile.vendorID ?? v.id;

if (!vendorProfiles[vendorID]) {
vendorProfiles[vendorID] = {};
}

if (!vendorProfiles[vendorID][regionProfile.id]) {
const profile = yaml.load(fs.readFileSync(`./vendor/${vendorID}/${regionProfile.id}.yaml`));
if (profile.vendorProfileID) {
console.log(`\n${key}: vendorProfileID exists. This method has been replaced with VendorIDs, see:`);
console.log(`https://github.com/TheThingsNetwork/lorawan-devices?tab=readme-ov-file#vendor-device-index`);
process.exit(1);
}
if (!validateEndDeviceProfile(profile)) {
console.error(
`${key}: profile ${vendorID}/${regionProfile.id} invalid: ${formatValidationErrors(
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"validate": "bin/validate.js"
},
"scripts": {
"install-hooks": "cp bin/pre-commit .git/hooks/ && chmod +x .git/hooks/pre-commit && echo 'hook copied'",
"validate": "node bin/validate.js",
"format": "prettier --write schema.json \"vendor/**/*.yaml\" \"bin/**/*.js\""
},
Expand Down
49 changes: 41 additions & 8 deletions schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,47 @@
"items": {
"$ref": "#/definitions/identifier"
}
},
"profileIDs": {
"type": "object",
"patternProperties": {
"^[0-9]+$": {
"oneOf": [
{
"type": "object",
"properties": {
"endDeviceID": {
"$ref": "#/definitions/identifier"
},
"hardwareVersion": {
"type": "string"
},
"firmwareVersion": {
"type": "string",
"minLength": 1
},
"region": {
"$ref": "#/definitions/region"
}
},
"required": ["endDeviceID", "hardwareVersion", "firmwareVersion", "region"]
},
{
"type": "object",
"properties": {
"id": {
"$ref": "#/definitions/identifier"
},
"codec": {
"$ref": "#/definitions/identifier"
}
},
"required": ["id", "codec"]
}
]
},
"additionalProperties": false
}
}
},
"additionalProperties": false
Expand Down Expand Up @@ -547,7 +588,6 @@
"type": "object",
"examples": [
{
"vendorProfileID": 1,
"supportsClassB": false,
"supportsClassC": false,
"macVersion": "1.0.2",
Expand All @@ -557,7 +597,6 @@
"supports32bitFCnt": true
},
{
"vendorProfileID": 2,
"supportsClassB": false,
"supportsClassC": false,
"macVersion": "1.0.4",
Expand All @@ -573,12 +612,6 @@
}
],
"properties": {
"vendorProfileID": {
"type": "integer",
"description": "VendorProfileID managed by the vendor, as defined in TR005",
"minimum": 0,
"maximum": 65535
},
"supportsClassB": {
"type": "boolean",
"description": "End device supports class B"
Expand Down
5 changes: 0 additions & 5 deletions vendor/abeeway/abeeway-compact-tracker-pro-as923.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# Vendor profile ID, can be freely issued by the vendor
# This vendor profile ID is also used on the QR code for LoRaWAN devices, see
# https://lora-alliance.org/sites/default/files/2020-10/LoRa_Alliance_Vendor_ID_for_QR_Code.pdf
vendorProfileID: 0

# LoRaWAN MAC version: 1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 or 1.1
macVersion: 1.0.2
# LoRaWAN Regional Parameters version. Values depend on the LoRaWAN version:
Expand Down
5 changes: 0 additions & 5 deletions vendor/abeeway/abeeway-compact-tracker-pro-eu868.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# Vendor profile ID, can be freely issued by the vendor
# This vendor profile ID is also used on the QR code for LoRaWAN devices, see
# https://lora-alliance.org/sites/default/files/2020-10/LoRa_Alliance_Vendor_ID_for_QR_Code.pdf
vendorProfileID: 0

# LoRaWAN MAC version: 1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 or 1.1
macVersion: 1.0.2
# LoRaWAN Regional Parameters version. Values depend on the LoRaWAN version:
Expand Down
5 changes: 0 additions & 5 deletions vendor/abeeway/abeeway-compact-tracker-pro-us915.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# Vendor profile ID, can be freely issued by the vendor
# This vendor profile ID is also used on the QR code for LoRaWAN devices, see
# https://lora-alliance.org/sites/default/files/2020-10/LoRa_Alliance_Vendor_ID_for_QR_Code.pdf
vendorProfileID: 0

# LoRaWAN MAC version: 1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 or 1.1
macVersion: 1.0.2
# LoRaWAN Regional Parameters version. Values depend on the LoRaWAN version:
Expand Down
5 changes: 0 additions & 5 deletions vendor/abeeway/abeeway-geolocation-module-profile.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# Vendor profile ID, can be freely issued by the vendor
# This vendor profile ID is also used on the QR code for LoRaWAN devices, see
# https://lora-alliance.org/sites/default/files/2020-10/LoRa_Alliance_Vendor_ID_for_QR_Code.pdf
vendorProfileID: 0

# LoRaWAN MAC version: 1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 or 1.1
macVersion: 1.0.2
# LoRaWAN Regional Parameters version. Values depend on the LoRaWAN version:
Expand Down
5 changes: 0 additions & 5 deletions vendor/abeeway/abeeway-industrial-tracker-pro-as923.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# Vendor profile ID, can be freely issued by the vendor
# This vendor profile ID is also used on the QR code for LoRaWAN devices, see
# https://lora-alliance.org/sites/default/files/2020-10/LoRa_Alliance_Vendor_ID_for_QR_Code.pdf
vendorProfileID: 0

# LoRaWAN MAC version: 1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 or 1.1
macVersion: 1.0.2
# LoRaWAN Regional Parameters version. Values depend on the LoRaWAN version:
Expand Down
5 changes: 0 additions & 5 deletions vendor/abeeway/abeeway-industrial-tracker-pro-eu868.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# Vendor profile ID, can be freely issued by the vendor
# This vendor profile ID is also used on the QR code for LoRaWAN devices, see
# https://lora-alliance.org/sites/default/files/2020-10/LoRa_Alliance_Vendor_ID_for_QR_Code.pdf
vendorProfileID: 0

# LoRaWAN MAC version: 1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 or 1.1
macVersion: 1.0.2
# LoRaWAN Regional Parameters version. Values depend on the LoRaWAN version:
Expand Down
5 changes: 0 additions & 5 deletions vendor/abeeway/abeeway-industrial-tracker-pro-us915.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# Vendor profile ID, can be freely issued by the vendor
# This vendor profile ID is also used on the QR code for LoRaWAN devices, see
# https://lora-alliance.org/sites/default/files/2020-10/LoRa_Alliance_Vendor_ID_for_QR_Code.pdf
vendorProfileID: 0

# LoRaWAN MAC version: 1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 or 1.1
macVersion: 1.0.2
# LoRaWAN Regional Parameters version. Values depend on the LoRaWAN version:
Expand Down
5 changes: 0 additions & 5 deletions vendor/abeeway/abeeway-micro-tracker-profile-as923.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# Vendor profile ID, can be freely issued by the vendor
# This vendor profile ID is also used on the QR code for LoRaWAN devices, see
# https://lora-alliance.org/sites/default/files/2020-10/LoRa_Alliance_Vendor_ID_for_QR_Code.pdf
vendorProfileID: 0

# LoRaWAN MAC version: 1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 or 1.1
macVersion: 1.0.2
# LoRaWAN Regional Parameters version. Values depend on the LoRaWAN version:
Expand Down
5 changes: 0 additions & 5 deletions vendor/abeeway/abeeway-micro-tracker-profile-eu868.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# Vendor profile ID, can be freely issued by the vendor
# This vendor profile ID is also used on the QR code for LoRaWAN devices, see
# https://lora-alliance.org/sites/default/files/2020-10/LoRa_Alliance_Vendor_ID_for_QR_Code.pdf
vendorProfileID: 0

# LoRaWAN MAC version: 1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 or 1.1
macVersion: 1.0.2
# LoRaWAN Regional Parameters version. Values depend on the LoRaWAN version:
Expand Down
5 changes: 0 additions & 5 deletions vendor/abeeway/abeeway-micro-tracker-profile-us915.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# Vendor profile ID, can be freely issued by the vendor
# This vendor profile ID is also used on the QR code for LoRaWAN devices, see
# https://lora-alliance.org/sites/default/files/2020-10/LoRa_Alliance_Vendor_ID_for_QR_Code.pdf
vendorProfileID: 0

# LoRaWAN MAC version: 1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 or 1.1
macVersion: 1.0.2
# LoRaWAN Regional Parameters version. Values depend on the LoRaWAN version:
Expand Down
5 changes: 0 additions & 5 deletions vendor/abeeway/abeeway-smart-badge-profile-as923.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# Vendor profile ID, can be freely issued by the vendor
# This vendor profile ID is also used on the QR code for LoRaWAN devices, see
# https://lora-alliance.org/sites/default/files/2020-10/LoRa_Alliance_Vendor_ID_for_QR_Code.pdf
vendorProfileID: 0

# LoRaWAN MAC version: 1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 or 1.1
macVersion: 1.0.2
# LoRaWAN Regional Parameters version. Values depend on the LoRaWAN version:
Expand Down
5 changes: 0 additions & 5 deletions vendor/abeeway/abeeway-smart-badge-profile-eu868.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# Vendor profile ID, can be freely issued by the vendor
# This vendor profile ID is also used on the QR code for LoRaWAN devices, see
# https://lora-alliance.org/sites/default/files/2020-10/LoRa_Alliance_Vendor_ID_for_QR_Code.pdf
vendorProfileID: 0

# LoRaWAN MAC version: 1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 or 1.1
macVersion: 1.0.2
# LoRaWAN Regional Parameters version. Values depend on the LoRaWAN version:
Expand Down
5 changes: 0 additions & 5 deletions vendor/abeeway/abeeway-smart-badge-profile-us915.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# Vendor profile ID, can be freely issued by the vendor
# This vendor profile ID is also used on the QR code for LoRaWAN devices, see
# https://lora-alliance.org/sites/default/files/2020-10/LoRa_Alliance_Vendor_ID_for_QR_Code.pdf
vendorProfileID: 0

# LoRaWAN MAC version: 1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 or 1.1
macVersion: 1.0.2
# LoRaWAN Regional Parameters version. Values depend on the LoRaWAN version:
Expand Down
5 changes: 0 additions & 5 deletions vendor/acrios/acr-cv-otaa-profile.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# Vendor profile ID, can be freely issued by the vendor
# This vendor profile ID is also used on the QR code for LoRaWAN devices, see
# https://lora-alliance.org/sites/default/files/2020-10/LoRa_Alliance_Vendor_ID_for_QR_Code.pdf
vendorProfileID: 01

# LoRaWAN MAC version: 1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 or 1.1
macVersion: 1.0.4
# LoRaWAN Regional Parameters version. Values depend on the LoRaWAN version:
Expand Down
Loading

0 comments on commit 3a8dc15

Please sign in to comment.