CLI: Error trying to register several devices

I’m trying to register several devices with CLI.
I could do it on ttnv2 but I can’t on ttnv3.
I have a file with devices parameters:

dev_id1   join_id1   dev_eui1   app_key1
dev_id2   join_id2   dev_eui2   app_key2
dev_id3   join_id3   dev_eui3   app_key3
...

And an script file with:

#!/bin/bash
...
...
FILE=$1
APPLICATION=$2
register_device()
{
        APP_ID=$1
        DEV_ID=$2
        JOIN_EUI=$3
        DEV_EUI=$4
        APP_KEY=$5
        ttn-lw-cli end-devices create $APP_ID $DEV_ID --join-eui $JOIN_EUI --dev-eui $DEV_EUI --root-keys.app-key.key $APP_KEY
}

while IFS= read -r device
do
        register_device $APPLICATION $device
done < "$FILE"

And I launch it with

:~$ ./script devices_file application

If I have only one device in my device_file, it works, and return json config structure.
However, if device_file has a carriage return at the end of the first line, it throws next error:
json: cannot unmarshal number into Go value of type map[string]interface {}
what can I do?
It seems to be an error due to the return json config, when ttn-lw-cli is executed

This is the big clue - you have to feed it a JSON formatted file …

There is mention in the docs about using a tab delimited file, but that’s for migration and only has one column. But you could parse your file and use it as parameters with some sort of loop rather than just pushing it all in in one go.

The file is delimited with spaces, but I wrote tabs (4 spaces) to let best reading.
The script uses a loop, it takes the necessary values to register only one device. The function register_device() gets only 5 input parameters for 1 register each time.
But, it seems that a json config is returned and I don’t know how to deal with it.

Thank you.

How can it have a variable $1 that is the App ID in the command line but then use have Dev ID as the first column.

Perhaps best print the command out to see what it’s trying to send?

But the JSON response is clear, it can’t cope with a number that it needs to turn in to a string - possibly it is a carriage return embedded in to the APP_KEY.

Hi, Descartes.
The code exposed is a part of the complete script. I have echoed the command before send it, and it is ok. If I try code with only one device and not carriage return, it works.
I have tried to remove the last character with tr -d ‘\n’ or awk and it still not working. I have echoed it with xxd, so Im sure that APP_KEY contains the expected characters.

Complete code script is next one:

#!/bin/bash

CURRENT_DIR=`pwd`
PATH=$PATH:/$CURRENT_DIR
APPLICATION=$2 

menu_ayuda() {
        echo -e -n "\n"
	echo "Uso: ttnctl_reg_masiva archivo de entrada"
	echo -e -n "\n"
	echo "Formato del archivo de entrada"
	echo -e " DEVICE_EUI APP_KEY"
        echo -e " DEVICE_EUI APP_KEY"
        echo -e " DEVICE_EUI APP_KEY"
	echo -e " ...\r\n"
}


# Selecciona el archivo de entrada
if [ -z $1 ]
then
       	echo "Seleccione un archivo para operación masiva"
       	menu_ayuda
       	exit 1
elif [ ! -e $1 ]
then
        echo "El archivo seleccionado no existe"
        exit 1
else
        FILE=$1
fi

register_device()
{
	JOIN_EUI=$2
	DEV_EUI=$3
	APP_KEY=`echo -n $4 | tr -d '\n'`
	DEV_ID=`echo $3 | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
	ttn-lw-cli end-devices create $1 $DEV_ID --join-eui $JOIN_EUI --dev-eui $DEV_EUI --root-keys.app-key.key $APP_KEY
	echo end-devices create $1 $DEV_ID --join-eui $JOIN_EUI --dev-eui $DEV_EUI --root-keys.app-key.key $APP_KEY
}

while IFS= read -r device
do
	register_device $APPLICATION $device
done < "$FILE"

I have found a dirty solution:
Instead of get echo con shell, I send it to a file:

...
echo end-devices create $1 $DEV_ID --join-eui /
$JOIN_EUI --dev-eui $DEV_EUI --root-keys.app-key.key 
$APP_KEY >> one_by_one.sh
...

one_by_one.sh contains the complete sentence for each device.

#!/bin/bash
ttn-lw-cli end-devices create app_id dev_id_1 --join-eui join_eui_1 --dev-eui dev_eui_1 --root-keys.app-key.key app_key_1
ttn-lw-cli end-devices create app_id dev_id_2 --join-eui join_eui_2 --dev-eui dev_eui_2 --root-keys.app-key.key app_key_2
ttn-lw-cli end-devices create app_id dev_id_3 --join-eui join_eui_3 --dev-eui dev_eui_3 --root-keys.app-key.key app_key_3

and:

:~$ ./one_by_one.sh app_id devices_file

it works

Cool - I’m working on some basic Python GUI interfaces which I’ll share once they are better formed.

Then I can link them to some sort of file reader for bulk registrations.