GIRNI

Grupo de Investigación de Redes de iNformación Inalámbricas

Categoría: LoRaWan - Parametros Up/Down

  • LoRaWan - Parámetros Up/Down: Pantalla Chirpstack y HA

    ChirpStack

    DECODER

    function Decode(fPort, bytes, variables) {
      var Down_rssi = -1*parseInt(bytes[0]);
      var Down_snr = bytes[1];
      var Down_datarate = bytes[2];
      // usando entero
      var unalectura = (bytes[4] << 8) |(bytes[3]);
      unalectura = (unalectura/1000);
      unalectura = +unalectura.toFixed(2);
      var appData = {'Down_rssi':Down_rssi,'Down_snr':Down_snr,
                     'Down_datarate':Down_datarate,
                     'bateria_V': unalectura}
      return appData;
    }
    

    ENCODER

    function Encode(fPort, obj, variables) {
      var UP_rssi = obj["UP_rssi"];
      // var Up_snr = obj["UP_snr"];
      var mensaje = [UP_rssi];
      return mensaje;
    }
    

    Home Assistant

    configuration.yaml

    mqtt:
      sensor:
        - name: "rssi_up_cc50"
          unique_id: cc27rssiup
          state_topic: "application/1/device/a53ec615aede3f50/event/up"
          unit_of_measurement: "dBm"
          value_template: "{{ value_json.rxInfo[0].rssi}}"
          #availability:
          #  - topic: "home/sensor1/status"
          payload_available: "online"
          payload_not_available: "offline"
          json_attributes_topic: "application/1/device/a53ec615aede3f50/event/up"

    Automation

    Desencadenante

    platform: mqtt
    topic: application/1/device/a53ec615aede3f50/event/up

    Acción

    service: mqtt.publish
    data:
      qos: 0
      retain: false
      topic: application/1/device/a53ec615aede3f50/command/down
      payload: '{"confirmed":false,"fPort":4,"object":{"UP_rssi":{{(states("sensor.rssi_up_cc50") | int)*(-1)}}}}'
  • LoRaWan - Parámetros Up/Down: Pantalla Archivo.ino

    Pantalla OLED con parametros RSSI UP/DOWN

    Probador de Rssi de subida y bajada

    Hardware: Heltec cubecell AB02, con pantalla OLED incorporada.

    OLED_pantalla.ino

    void displayconectando(){
    	display2.setFont(ArialMT_Plain_16);
    	display2.setTextAlignment(TEXT_ALIGN_CENTER);
    	display2.clear();
    	display2.drawString(58, 22, "Joining...");
    	display2.display();
    }
    void displayConectado(){
    	display2.clear();
    	display2.drawString(64, 22, "Conectado_OK");
    	display2.display();
    	delay(500);
    }
    void displayTransmitiendo(){
    	digitalWrite(Vext,LOW);
    	display2.init();
    	display2.setFont(ArialMT_Plain_16);
    	display2.setTextAlignment(TEXT_ALIGN_CENTER);
    	display2.clear();
    	display2.drawString(58, 22, "Tx...");
    	display2.display();
    	delay(500);
    }
    void displayPaqRecibido(){
      char temp[25];
    	display2.clear();
      display2.setFont(ArialMT_Plain_16);
      display2.setTextAlignment(TEXT_ALIGN_LEFT);
      sprintf(temp,"Rx snr:%d,dr:%d",Down_snr, Down_datarate);
    	display2.drawString(0, 0, temp); //22
    	sprintf(temp,"rssiDw: -%d",Down_rssi);
    	display2.setFont(ArialMT_Plain_24);
    	display2.setTextAlignment(TEXT_ALIGN_RIGHT);
    	display2.drawString(128, 16, temp);
      sprintf(temp,"rssiUp: -%d",Up_rssi);
    	display2.setFont(ArialMT_Plain_24);
    	display2.setTextAlignment(TEXT_ALIGN_RIGHT);
    	display2.drawString(128, 40, temp);
    
      display2.drawString(0,0, temp);
    	if(loraWanClass==CLASS_A)	{
    		display2.setFont(ArialMT_Plain_10);
    		display2.setTextAlignment(TEXT_ALIGN_LEFT);
    		display2.drawString(28, 50, "Into deep sleep in 2S");
    	}
    	display2.display();
      delay(10000);
      display2.clear();
    	if(loraWanClass==CLASS_A){
    		digitalWrite(Vext,HIGH);
    		display2.stop();
    	}
    }
    
    void displayAckRecibido(){
      char temp[25];
    	display2.clear();
      display2.setFont(ArialMT_Plain_16);
      display2.setTextAlignment(TEXT_ALIGN_LEFT);
      sprintf(temp,"ACK snr:%d,dr:%d",confirmaSnr, confirmaDatarate);
    	display2.drawString(0, 0, temp); //22
    	sprintf(temp,"rssiDw: -%d",confirmaRssi);
    	display2.setFont(ArialMT_Plain_24);
    	display2.setTextAlignment(TEXT_ALIGN_RIGHT);
    	display2.drawString(128, 16, temp);
    	if(loraWanClass==CLASS_A)	{
    		display2.setFont(ArialMT_Plain_10);
    		display2.setTextAlignment(TEXT_ALIGN_LEFT);
    		display2.drawString(28, 50, "Into deep sleep in 2S");
    	}
    	display2.display();
      delay(10000);
    	if(loraWanClass==CLASS_A)	{
    		digitalWrite(Vext,HIGH);
    		display2.stop();
    	}
    }
    

    CubeCell_Practicas2023OLED.ino

    // Lectura de Rssi Snr, datarate Up/Downlink
    // Datos Downlink de la trama de confirmación anterior
    // http://blog.espol.edu.ec/girni/lorawan-enlaces-up-down-archivo-ino/
    #include "LoRaWan_APP.h"
    #include "Arduino.h"
    #include <Wire.h>               
    #include "HT_SH1107Wire.h"
    
    SH1107Wire  display2(0x3c, 500000, SDA, SCL ,GEOMETRY_128_64,GPIO10); // addr, freq, sda, scl, resolution, rst
    
    /* set LoraWan_RGB to Active,the RGB active in loraWan
     * red   |sending;   purple | joined done;
     * blue  |RxWindow1; yellow | means RxWindow2;
     * green | received done;
     */
    /* Conexión LoRa: OTAA parametros*/
    uint8_t devEui[] = { 0xa5, 0x3e, 0xc6, 0x15, 0xae, 0xde, 0x3f, 0x50 };
    uint8_t appEui[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    uint8_t appKey[] = { 0x88, 0xbe, 0x25, 0xca, 0x2c, 0xcf, 0x31, 0x85,
                         0x51, 0x2d, 0xee, 0xe2, 0x80, 0x31, 0x8e, 0x01 };
    /* ABP parametros*/
    uint8_t nwkSKey[] = { 0x15, 0xb1, 0xd0, 0xef, 0xa4, 0x63, 0xdf, 0xbe,
                          0x3d, 0x11, 0x18, 0x1e, 0x1e, 0xc7, 0xda,0x85 };
    uint8_t appSKey[] = { 0x47, 0xdc, 0xac, 0x5f, 0xc2, 0x32, 0x24, 0x31, 
                          0xdf, 0xf1, 0xff, 0xf9, 0x46, 0xe5, 0x2e, 0x17 };
    uint32_t devAddr =  ( uint32_t )0x007bc4150;
    /*LoraWan channelsmask, default channels 0-7*/ 
    uint16_t userChannelsMask[6]={ 0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000 };
    
    /*Select in arduino IDE tools*/
    LoRaMacRegion_t loraWanRegion = ACTIVE_REGION;
    DeviceClass_t  loraWanClass = LORAWAN_CLASS;
    bool overTheAirActivation = LORAWAN_NETMODE;
    bool loraWanAdr = LORAWAN_ADR;
    bool keepNet = LORAWAN_NET_RESERVE;
    bool isTxConfirmed = LORAWAN_UPLINKMODE;
    
    uint8_t duermemin = 0; //15
    uint8_t duermeseg = 300; //0
    
    uint32_t appTxDutyCycle = (duermemin*60 + duermeseg)*1000; // min*seg*ms
    
    uint8_t appPort = 4; /* Application port */
    /* trials to transmit frame, if didn't receive ack.
     * The MAC performs a datarate adaptation,
     * Tx nb|Data Rate
     * -----|----------
     * 1    |DR           * 5    | max(DR-2,0)
     * 2    |DR           * 6    | max(DR-2,0)
     * 3    |max(DR-1,0)  * 7    | max(DR-3,0)
     * 4    |max(DR-1,0)  * 8    | max(DR-3,0)
    */
    uint8_t confirmedNbTrials = 4;
    
    // Ack parametros de recepción
    uint8_t confirmaRssi = 0;
    uint8_t confirmaSnr = 0;
    uint8_t confirmaDatarate = 0;
    
    // Ack parametros de recepción
    uint8_t Down_rssi = 0;
    uint8_t Down_snr = 0;
    uint8_t Down_datarate = 0;
    
    uint8_t Up_rssi = 0;
    
    uint8_t itera = 0;
    uint8_t estado = 0; //0x00, 0x01,"OFF","ON"
    
    void setup() {
    	Serial.begin(115200);
     
    #if(AT_SUPPORT)
    	enableAt();
    #endif
    
      // OLED display status
      //LoRaWAN.displayMcuInit();
      
    	deviceState = DEVICE_STATE_INIT;
    	//LoRaWAN.ifskipjoin(); //if joinned,skip
    
      display2.init();
      display2.setFont(ArialMT_Plain_10);
    }
    
    void loop() {
      Serial.print(".");
      itera = itera + 1;
      if (itera>6){
        itera = 0;
        Serial.println(" ");
      }
    	switch( deviceState ) {
    		case DEVICE_STATE_INIT: {
    #if(LORAWAN_DEVEUI_AUTO)
    			LoRaWAN.generateDeveuiByChipID();
    #endif
    #if(AT_SUPPORT)
    			getDevParam();
    #endif
    			printDevParam();
    			LoRaWAN.init(loraWanClass,loraWanRegion);
    			deviceState = DEVICE_STATE_JOIN;
    			break;
    		}
    		case DEVICE_STATE_JOIN: {
          //LoRaWAN.displayJoining();
          displayconectando();
    			LoRaWAN.join();
    			break;
    		}
    		case DEVICE_STATE_SEND:	{
          //LoRaWAN.displaySending();
          displayTransmitiendo();
    			prepareTxFrame( appPort );
    			LoRaWAN.send();
    			deviceState = DEVICE_STATE_CYCLE;
    			break;
    		}
    		case DEVICE_STATE_CYCLE: {
    			// Schedule next packet transmission
    			txDutyCycleTime = appTxDutyCycle + randr( 0, APP_TX_DUTYCYCLE_RND );
    			LoRaWAN.cycle(txDutyCycleTime);
    			deviceState = DEVICE_STATE_SLEEP;
    			break;
    		}
    		case DEVICE_STATE_SLEEP: {
          //LoRaWAN.displayAck();
    			LoRaWAN.sleep();
    			break;
    		}
    		default: {
    			deviceState = DEVICE_STATE_INIT;
    			break;
    		}
    	}
    }
    

    LoRaWanEnvia.ino

    /* Prepares the payload of the frame */
    static void prepareTxFrame( uint8_t port ) {
      // enciende sensor
      pinMode(Vext, OUTPUT);
      digitalWrite(Vext, LOW);
      //Lectura de Sensor
    
      //apaga sensor
      digitalWrite(Vext, HIGH);
      
      // lectura de bateria  
      uint16_t batteryVoltage = getBatteryVoltage();
      unsigned char *puc;
    
      // trama
      appDataSize = 5;
      appData[0] = confirmaRssi; //Ack leido en dispositivo
      appData[1] = confirmaSnr;
      appData[2] = confirmaDatarate;
      appData[3] = (uint8_t)batteryVoltage;
      appData[4] = (uint8_t)(batteryVoltage>>8);
    
      Serial.print("%, Bateria = ");
      Serial.println(batteryVoltage);
    }
    

    LoRaWanRecibe.ino

    //downlink data handle function example
    void downLinkDataHandle(McpsIndication_t *mcpsIndication){
      // parametros de recepcion
      Down_rssi = uint8_t(abs(mcpsIndication->Rssi));
      Down_snr  = uint8_t(mcpsIndication->Snr);
      Down_datarate = uint8_t(mcpsIndication->RxDoneDatarate);
      // recibido de trama
      Up_rssi = uint8_t(mcpsIndication->Buffer[0]);
    
      //
      Serial.print("Rx Down_rssi:-"); Serial.print(Down_rssi);
      Serial.print(", Down_snr:");Serial.print(Down_snr);
      Serial.print(", Down_datarate: ");Serial.println(Down_datarate);
      Serial.print(" UP_rssi:");
      Serial.print(-1*Up_rssi);
      Serial.printf(" +REV DATA:%s,RXSIZE %d,PORT %d\r",mcpsIndication->RxSlot?"RXWIN2":"RXWIN1",mcpsIndication->BufferSize,mcpsIndication->Port);
      Serial.println();
      
      displayPaqRecibido();
    }
    

    LoRaWanRecibeConfirma.ino

    void downLinkAckHandle(McpsIndication_t *mcpsIndication){
      // ACK parametros de recepcion
      confirmaRssi = uint8_t(abs(mcpsIndication->Rssi));
      confirmaSnr  = uint8_t(mcpsIndication->Snr);
      confirmaDatarate = uint8_t(mcpsIndication->RxDoneDatarate);
    
      Serial.println("");
      Serial.print(" ack received(rssi,snd,datarate): -");
      Serial.print(confirmaRssi);Serial.print(" ,");
      Serial.print(confirmaSnr);Serial.print(" ,");
      Serial.println(confirmaDatarate);
      
      displayAckRecibido();
    }
    
  • LoRaWan - Parámetros Up/Down: Chirpstack y HA

    Las instrucciones para interpretar la trama en el gestor de gateways  se realizan en JavaScript, siguiendo el mismo orden de bytes realizado en el dispositivo.

    Con esta parte se habilita la lectura de los parámetros para gestionar los datos en HomeAssistant mediante un mensaje Mqtt.

    function Decode(fPort, bytes, variables) {
      var Down_rssi = -1*parseInt(bytes[0]);
      var Down_snr = bytes[1];
      var Down_datarate = bytes[2];
      // usando entero
      var unalectura = (bytes[4] &lt;&lt; 8) |(bytes[3]);
      unalectura = (unalectura/1000)
      unalectura = +unalectura.toFixed(2);
      var appData = {'Down_rssi':Down_rssi,
                     'Down_snr':Down_snr,
                     'Down_datarate':Down_datarate,
                     'bateria_V': unalectura}
      return appData;
    }
    

    función de codificación hacia el dispositivo, Reenvía al dispositivo el Rssi de Uplink del paquete anterior

    function Encode(fPort, obj) {
      var data = new Array();
      data[0] = -1*parseInt(obj["Up_rssi"])
      return data;
    }

    Automatización en Home-Assistant

    Para reenviar el Rssi de UpLink hacia el dispositivo para registrar valores en el punto de muestra:

    alias: cc01UpRssi_reenviar
    description: reenviar cc01 Up_rssi al dispositivo
    trigger:
      - platform: state
        entity_id: sensor.rssi_up_cc01
    action:
      - service: mqtt.publish
        data_template:
          topic: application/1/device/a53ec615aede3f01/command/down
          payload_template: >-
            {"confirmed":false,"fPort":3,"object":{"Up_rssi":{{
            trigger.to_state.state }}}}
  • LoRaWan - Parámetros Up/Down: Archivo.ino

    LoRaWan - Enlaces Up/Down Parámetros

    Para realizar pruebas de conectividad y calidad del enlace inalámbrico, se propone usar dispositivos con una configuración básica que registre los parámetros del enlace de subida y bajada.

    Los parámetros para subida (Uplink) se obtienen desde el gateway, de los parámetros regulares que registra el gateway.

    Los parámetros de bajada (Downlink) se obtienen de la trama de confirmación (Acknowlegment) que son Rssi, Snr y datarate. Estos parámetros se usan en el próximo envío de datos (Uplink) por lo que presentan un atraso equivalente al intervalo de lectura de datos del dispositivo.

    El dispositivo para la prueba se implementa con un módulo de desarrollo HELTEC Cubecell Board-Plus HTCC-AB02.

    Preparación de trama

    La trama se configura usando los parámetros obtenidos en el dispositivo con una trama de confirmación de subida (Ack). El primer valor enviado será cero, puesto que no se dispone de parámetros iniciales.

    • Rssi Downlink (1 byte)
    • Snr Downlink (1 byte)
    • Datarate Downlink (1 byte)
    • Voltaje de bateria (2 bytes)
    // Ack parametros de recepción
    uint8_t confirmaRssi = 0;
    uint8_t confirmaSnr = 0;
    uint8_t confirmaDatarate = 0;

    A Septiembre del 2021, se usan las librerías publicadas para el módulo HELTEC Cubecell Board-Plus HTCC-AB02. Para obtener los parámetros de la trama de confirmación de recibido (Ack) el gateway para una trama de subida de datos (Uplink) se sustituye el procedimiento:

    downLinkAckHandle(McpsIndication_t *mcpsIndication)

    Las instrucciones para el manejo de LoraWan se pueden revisar en:

    https://github.com/HelTecAutomation/CubeCell-Arduino/blob/master/libraries/LoRa/src/LoRaWan_APP.cpp

    El archivo LoRaWan_APP.cpp se encuentra instalado en el directorio de windows:

    C:\Users\MiUsuario\AppData\Local\Arduino15\packages
      \CubeCell\hardware\CubeCell\1.3.0\libraries\LoRa\src

    desde donde es posible complementar las instrucciones usando un editor de texto en las líneas corespondientes:

    void __attribute__((weak)) downLinkAckHandle()
    {
    	//printf("ack received\r\n");
    }

    para indicar los parámetros a usar al recibir la trama Ack:

    void __attribute__((weak)) downLinkAckHandle(McpsIndication_t *mcpsIndication)
    {
    	//printf("ack received\r\n");
    }

    adicionalmente, en el mismo archivo, más adelante:

    static void McpsIndication( McpsIndication_t *mcpsIndication )
    ....
    	if(mcpsIndication->AckReceived)
    	{
    		downLinkAckHandle(mcpsIndication);
    	}

    con lo que es posible usar las instrucciones del dispositivo para obtener los parámetros indicados para la trama de confirmación de recibo (Ack)

    Parámetros de trama de confirmación de recibido - Ack

    LoRaWan Enlace UpDown Parametros Ack
    void downLinkAckHandle(McpsIndication_t *mcpsIndication){
      confirmaRssi = uint8_t(abs(mcpsIndication->Rssi));
      confirmaSnr  = uint8_t(mcpsIndication->Snr);
      confirmaDatarate = uint8_t(mcpsIndication->RxDoneDatarate);
      Serial.print(" ack received(rssi,snd,datarate): -");
      Serial.print(confirmaRssi);Serial.print(" ,");
      Serial.print(confirmaSnr);Serial.print(" ,");
      Serial.println(confirmaDatarate);
    }
    

    con los parámetros obtenidos y añadiendo el voltaje de la batería, se conforma la trama a enviar.

    LoRaWan Enlace UpDown Enviar
    /* Prepares the payload of the frame */
    static void prepareTxFrame( uint8_t port ) {
      // enciende sensor
      pinMode(Vext, OUTPUT);
      digitalWrite(Vext, LOW);
      
      //Lectura de Sensor
    
      // apaga sensor
      digitalWrite(Vext, HIGH);
      
      // lectura de bateria  
      uint16_t batteryVoltage = getBatteryVoltage();
      unsigned char *puc;
    
      // trama
      appDataSize = 5;
      appData[0] = confirmaRssi; //Ack leido en dispositivo
      appData[1] = confirmaSnr;
      appData[2] = confirmaDatarate;
      appData[3] = (uint8_t)batteryVoltage;
      appData[4] = (uint8_t)(batteryVoltage>>8);
    
      Serial.print("%, Bateria = ");
      Serial.println(batteryVoltage);
    }
    

    Instrucciones Principales

    LoRaWan Enlace UpDown Principal
    #include "LoRaWan_APP.h"
    #include "Arduino.h"
    
    /* set LoraWan_RGB to Active,the RGB active in loraWan
     * red   |sending;   purple | joined done;
     * blue  |RxWindow1; yellow | means RxWindow2;
     * green | received done;
     */
    /* Conexión LoRa: OTAA parametros*/
    uint8_t devEui[] = { 0xa6, 0x17, 0x74, 0xe9, 0x5c, 0x1c, 0x98, 0xbd };
    uint8_t appEui[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    uint8_t appKey[] = { 0x76, 0x9d, 0x1b, 0xc3, 0xf9, 0xe6, 0x7b, 0xbd,
                         0xa3, 0x4d, 0xe3, 0xcf, 0xbc, 0x8e, 0x35, 0x8f };
    /* ABP parametros*/
    uint8_t nwkSKey[] = { 0x15, 0xb1, 0xd0, 0xef, 0xa4, 0x63, 0xdf, 0xbe,
                          0x3d, 0x11, 0x18, 0x1e, 0x1e, 0xc7, 0xda,0x85 };
    uint8_t appSKey[] = { 0x47, 0xdc, 0xac, 0x5f, 0xc2, 0x32, 0x24, 0x31, 
                          0xdf, 0xf1, 0xff, 0xf9, 0x46, 0xe5, 0x2e, 0x17 };
    uint32_t devAddr =  ( uint32_t )0x007bc4af;
    /*LoraWan channelsmask, default channels 0-7*/ 
    uint16_t userChannelsMask[6]={ 0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000 };
    
    /*Select in arduino IDE tools*/
    LoRaMacRegion_t loraWanRegion = ACTIVE_REGION;
    DeviceClass_t  loraWanClass = LORAWAN_CLASS;
    bool overTheAirActivation = LORAWAN_NETMODE;
    bool loraWanAdr = LORAWAN_ADR;
    bool keepNet = LORAWAN_NET_RESERVE;
    bool isTxConfirmed = LORAWAN_UPLINKMODE;
    
    uint32_t appTxDutyCycle = 1*15*1000;
    uint8_t appPort = 2; /* Application port */
    /* trials to transmit frame, if didn't receive ack.
     * The MAC performs a datarate adaptation,
     * Tx nb|Data Rate
     * -----|----------
     * 1    |DR           * 5    | max(DR-2,0)
     * 2    |DR           * 6    | max(DR-2,0)
     * 3    |max(DR-1,0)  * 7    | max(DR-3,0)
     * 4    |max(DR-1,0)  * 8    | max(DR-3,0)
    */
    uint8_t confirmedNbTrials = 4;
    
    // Ack parametros de recepción
    uint8_t confirmaRssi = 0;
    uint8_t confirmaSnr = 0;
    uint8_t confirmaDatarate = 0;
    
    uint8_t itera = 0;
    
    void setup() {
    	Serial.begin(115200);
    #if(AT_SUPPORT)
    	enableAt();
    #endif
      LoRaWAN.displayMcuInit();
    	deviceState = DEVICE_STATE_INIT;
    	LoRaWAN.ifskipjoin(); //if joinned,skip
    }
    
    void loop() {
      Serial.print(".");
      itera = itera + 1;
      if (itera>6){
        itera = 0;
        Serial.println(" ");
      }
    	switch( deviceState ) {
    		case DEVICE_STATE_INIT: {
    #if(LORAWAN_DEVEUI_AUTO)
    			LoRaWAN.generateDeveuiByChipID();
    #endif
    #if(AT_SUPPORT)
    			getDevParam();
    #endif
    			printDevParam();
    			LoRaWAN.init(loraWanClass,loraWanRegion);
    			deviceState = DEVICE_STATE_JOIN;
    			break;
    		}
    		case DEVICE_STATE_JOIN: {
          LoRaWAN.displayJoining();
    			LoRaWAN.join();
    			break;
    		}
    		case DEVICE_STATE_SEND:	{
          LoRaWAN.displaySending();
    			prepareTxFrame( appPort );
    			LoRaWAN.send();
    			deviceState = DEVICE_STATE_CYCLE;
    			break;
    		}
    		case DEVICE_STATE_CYCLE: {
    			// Schedule next packet transmission
    			txDutyCycleTime = appTxDutyCycle + randr( 0, APP_TX_DUTYCYCLE_RND );
    			LoRaWAN.cycle(txDutyCycleTime);
    			deviceState = DEVICE_STATE_SLEEP;
    			break;
    		}
    		case DEVICE_STATE_SLEEP: {
          LoRaWAN.displayAck();
    			LoRaWAN.sleep();
    			break;
    		}
    		default: {
    			deviceState = DEVICE_STATE_INIT;
    			break;
    		}
    	}
    }
    

    y en el caso de recibir instrucciones para el dispositivo, se dispone de un ejemplo:

    //downlink data handle function example
    void downLinkDataHandle(McpsIndication_t *mcpsIndication){
      // revisa parametros
      Serial.print("\nLLEGo un mensaje para dispositivo...");
      Serial.print("Rssi: ");
      Serial.println(mcpsIndication->Rssi);
      
      Serial.printf("+REV DATA:%s,RXSIZE %d,PORT %d\r\n",
      mcpsIndication->RxSlot?"RXWIN2":"RXWIN1",
      mcpsIndication->BufferSize,mcpsIndication->Port);
      Serial.print("+REV DATA:");
      for(uint8_t i=0;i<mcpsIndication->BufferSize;i++)
      {
        Serial.printf("%02X",mcpsIndication->Buffer[i]);
      }
      Serial.println();
      uint32_t color=mcpsIndication->Buffer[0]<<16|mcpsIndication->Buffer[1]<<8|mcpsIndication->Buffer[2];
    #if(LoraWan_RGB==1)
      turnOnRGB(color,5000);
      turnOffRGB();
    #endif
    }