#include <lmic.h>
#include <hal/hal.h>
#include <LowPower.h>

const lmic_pinmap lmic_pins = {
    .nss = 10,
    .rxtx = LMIC_UNUSED_PIN,
    .rst = 9,
    .dio = {2, 5, LMIC_UNUSED_PIN},
};

#define TXPERIOD  (5*60) // 5 minutes

static const u1_t PROGMEM APPEUI[8] = {0x60, 0x81, 0xF9, 0x00, 0xF0, 0x00, 0x8E, 0x6B};
static const u1_t PROGMEM DEVEUI[8] = {0x60, 0x81, 0xF9, 0xB8, 0x34, 0x79, 0xA3, 0xFB};
static const u1_t PROGMEM APPKEY[16] = {0xC3, 0x6F, 0xAE, 0x48, 0xDD, 0xB3, 0xE7, 0x38, 0x91, 0x2A, 0x55, 0xA6, 0x4B, 0x9B, 0xEC, 0x6D};

void os_getArtEui (u1_t* buf) { 
  for ( int i = 0 ; i < 8 ; i++ ) buf[7-i] = APPEUI[i];
}
void os_getDevEui (u1_t* buf) { 
  for ( int i = 0 ; i < 8 ; i++ ) buf[7-i] = DEVEUI[i];
}
void os_getDevKey (u1_t* buf) {   
  memcpy_P(buf, APPKEY, 16);
}

void setup() {

    os_init();    // Intialisation de la bibliothèque
    LMIC_reset();
    LMIC_setClockError(MAX_CLOCK_ERROR * 10 / 100); // agrandit la fenetre de reception
    LMIC_setAdrMode(0);  // desactive le mode ADR
    // Configure les canaux utilisables pour les communications  
    LMIC_setupChannel(0, 868 100 000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      
    LMIC_setupChannel(1, 868 300 000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI);      
    LMIC_setupChannel(2, 868 500 000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      
    LMIC_setupChannel(3, 867 100 000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      
    LMIC_setupChannel(4, 867 300 000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);     
    LMIC_setupChannel(5, 867 500 000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);     
    LMIC_setupChannel(6, 867 700 000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      
    LMIC_setupChannel(7, 867 900 000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);     
    LMIC_setupChannel(8, 868 800 000, DR_RANGE_MAP(DR_FSK,  DR_FSK),  BAND_MILLI);    
    // Configure la vitesse et la puissance de transmission   
    LMIC.dn2Dr = SF9; 
    LMIC_setDrTxpow(DR_SF9,14); 
    LMIC_setLinkCheckMode(0); 
}

boolean canSleep = true;
uint32_t temps = TXPERIOD;  // transmettre au demarrage
uint8_t data[] = {
   0x01, 0x68, 0x00,     // canal 1, type de donnée Hygrometrie 1 ut = 0,5%
};

void loop() {
  if ( temps >= TXPERIOD ) {
        canSleep = false;
        // lecture de la donnée du capteur
        int16_t v = analogRead(A0); // 100 % = 313 | 50% = 678 
        data[2] = map(v, 636, 450, 0, 100) * 2;
        // emission de la valeur
        LMIC_setDrTxpow(DR_SF9,14); 
        lmic_tx_error_t err = LMIC_setTxData2(1, data, sizeof(data), 0);
        temps=0;        
  }
  // put your main code here, to run repeatedly:
  os_runloop_once();
  if ( canSleep ) {
    LowPower.powerDown(SLEEP_8S, ADC_OFF,BOD_OFF);
    temps += 8;
  }
}

void onEvent (ev_t ev) {
    switch(ev) {
        case EV_JOINED:
            LMIC_setLinkCheckMode(0);
            break;
        case EV_TXCOMPLETE: 
            canSleep = true;
            break;
        default:
            canSleep = false;
            break;
    }
}