// For Visegrad project Internet of things brainstorm workshop
// Include Hardwario components from Tower Industrial IoT kit
// Components: Battery modul, Split module, Core modul, Climate module, LCD modul, Sigfox modul, Radio dongle
// Functionality: measuring temperature (two values), humidity, atmosphere pressure, light intensity -> debugging on terminal -> displaying on LCD + PC -> sending data to Sigfox -> displaying on smartphone 
// Thanks: Harwario for VIP discount
// Thanks: Simple Cell Slovakia, s.r.o. for free account to Sigfox net
// Author: Vladimir Bobot on the bassis of Hardwario SDK, October, 2021 

#include <application.h>


//definovanie konstant
//#define x 10 bez bodkociarky definuje konstantu, ktoru vyuzivam v kode
#define SENSOR_UPDATE_INTERVAL_SECONDS 15 // kazdych 5 sekund sa spusta event handler pre climate modul (v kode pre climate 10*1000)
#define REGULAR_REPORT_SECONDS (15 * 60)// kazdych 15 min sa spusta event handler pre Sigfox

// LED instance na Core moduly
twr_led_t led;

// Button instance
//twr_button_t button;

// Thermometer instance
twr_tmp112_t tmp112; //temperature sensor on Core modul
//uint16_t button_click_count = 0;

// LCD Graphics GFX instance
twr_gfx_t *pgfx;

//Sigfox instance
twr_module_sigfox_t sigfox_module;

/*// Button event callback
void button_event_handler(twr_button_t *self, twr_button_event_t event, void *event_param)
{
    // Log button event
    twr_log_info("APP: Button event: %i", event);

    // Check event source
    if (event == TWR_BUTTON_EVENT_CLICK)
    {
        // Toggle LED pin state
        twr_led_set_mode(&led, TWR_LED_MODE_TOGGLE);

         // Publish message on radio
        button_click_count++;
        twr_radio_pub_push_button(&button_click_count);
    }
}
*/

/*
//nepouzijem meranie teploty z Core senzoru 
void tmp112_event_handler(twr_tmp112_t *self, twr_tmp112_event_t event, void *event_param)
{
    if (event == TWR_TMP112_EVENT_UPDATE)
    {
        float celsius;
        // Read temperature from Core modul
        twr_tmp112_get_temperature_celsius(self, &celsius);
        static char temp1[25]; 
        sprintf(temp1, "Temp1: %.2f%c C", celsius, 176);//176 je stupen celzia
        //twr_gfx_draw_string(pgfx, 10, 5, "Temp1: ", true);
        twr_gfx_draw_string(pgfx, 10, 5, temp1, true);
        //twr_gfx_update(pgfx);
        //twr_log_debug("APP: temperature: %.1f °C", celsius);//premennu celsius typu float zaokruhli na 1 desatinne miesto 
        //twr_radio_pub_temperature(TWR_RADIO_PUB_CHANNEL_R1_I2C0_ADDRESS_ALTERNATE, &celsius);//zatial nevysielame
    }
}
*/


 static   float_t temperature;
 static   float_t humidity;
 static   float_t illuminance;
 static   float_t pressure;
 static   float_t voltage;
 static   int charge_percentage;
 static char temp2[25]; 
 static char hum[25]; 
 static char illu[25];
 static char pres[25]; 
 static char volt[25];
 static char charge[25];


void climate_module_event_handler(bc_module_climate_event_t event, void *event_param)
{
    // OK handler sa spusta kazdych n sekund podla nastavenia v Application_Init (set_update_interval)
    (void) event_param;
    //static int counter = 0;
    //twr_log_debug("LCD HANDLER: %d)", ++counter);
    twr_gfx_clear(pgfx);

    if (event == BC_MODULE_CLIMATE_EVENT_UPDATE_THERMOMETER)
    {
        //float temperature;
        if (bc_module_climate_get_temperature_celsius(&temperature))
        {
            //twr_gfx_clear(pgfx);
            twr_log_debug("TEMP: %.2f", temperature);//funguje
            //bc_data_stream_feed(&stream_thermometer, &temperature);
            //static char temp2[25]; 
            //snprintf(temp2, sizeof(temp2), "%.2f", temperature);
            sprintf(temp2, "Temp: %.1f%c C", temperature, 176);
            //twr_gfx_draw_string(pgfx, 10, 5, temp2, true);
            //twr_gfx_update(pgfx);
            //twr_gfx_draw_string(pgfx, 10, 20, strcat("Temp2: ", t2), true);//strcat spoji dva stringy do jedneho
            //twr_gfx_draw_string(pgfx, 10, 20, t2, true);//strcat spoji dva stringy do jedneho
        }
        else
        {
            //bc_data_stream_reset(&stream_thermometer);
        }
    }
    else if (event == BC_MODULE_CLIMATE_EVENT_UPDATE_HYGROMETER)
    {
        //float humidity;
        if (bc_module_climate_get_humidity_percentage(&humidity))
        {
            //twr_gfx_clear(pgfx);
            //bc_data_stream_feed(&stream_hygrometer, &humidity);
            //static char hum[50]; 
            //snprintf(hum, sizeof(hum), "%.2f", humidity);
            sprintf(hum, "Humi: %.0f %c", humidity, 37);
            //twr_gfx_draw_string(pgfx, 10, 20, hum, true);
            //twr_gfx_update(pgfx);
        }
        else
        {
            //bc_data_stream_reset(&stream_hygrometer);
        }
    }
    else if (event == BC_MODULE_CLIMATE_EVENT_UPDATE_LUX_METER)
    {
        //float illuminance;
        if (bc_module_climate_get_illuminance_lux(&illuminance))
        {
            //twr_gfx_clear(pgfx);
            //bc_data_stream_feed(&stream_lux_meter, &illuminance);
            //static char illu[25]; 
            sprintf(illu, "Light: %.0f lx", illuminance);
            //twr_gfx_draw_string(pgfx, 10, 35, illu, true);
            //twr_gfx_update(pgfx);
        }
        else
        {
            //bc_data_stream_reset(&stream_lux_meter);
        }
    }
    else if (event == BC_MODULE_CLIMATE_EVENT_UPDATE_BAROMETER)
    {
        //float pressure = 0.0;
        if (bc_module_climate_get_pressure_pascal(&pressure))
        {
            //twr_gfx_clear(pgfx);
            //bc_data_stream_feed(&stream_barometer, &pressure);
            //static char pres[25]; 
            sprintf(pres, "Press: %.0f Pa", pressure);
            //twr_gfx_draw_string(pgfx, 10, 50, pres, true);
            //twr_gfx_update(pgfx);
        }
        else
        {
            //bc_data_stream_reset(&stream_barometer);
        }
    }
    //twr_gfx_clear(pgfx);
    //sprintf(temp2, "Temp: %.2f%c C", temperature, 176);
    //sprintf(hum, "Humi: %.0f %c", humidity, 37);
    //sprintf(illu, "Light: %.0f lx", illuminance);
    //sprintf(pres, "Press: %.0f Pa", pressure);
    twr_gfx_draw_string(pgfx, 10, 5, "Slovakia", true);
    twr_gfx_draw_line(pgfx, 10, 25, 110, 25, true); 
    twr_gfx_draw_string(pgfx, 10, 30, temp2, true);
    twr_gfx_draw_string(pgfx, 10, 45, hum, true);
    twr_gfx_draw_string(pgfx, 10, 60, illu, true);
    twr_gfx_draw_string(pgfx, 10, 75, pres, true);

    sprintf(volt, "Voltage: %.1f V", voltage);
    sprintf(charge, "Charge: %d %c", charge_percentage, 37);
    twr_module_battery_measure();
    twr_module_battery_get_voltage(&voltage);
    twr_module_battery_get_charge_level(&charge_percentage);
    twr_gfx_draw_string(pgfx,10, 90, volt, true);
    twr_gfx_draw_string(pgfx,10, 105, charge, true);

    twr_gfx_update(pgfx); //musim updetovat novy LCD
    //twr_module_lcd_update(); //update starsieho LCD

     twr_radio_pub_barometer(TWR_RADIO_PUB_CHANNEL_R1_I2C0_ADDRESS_DEFAULT, &pressure,0);
     twr_radio_pub_luminosity(TWR_RADIO_PUB_CHANNEL_R1_I2C0_ADDRESS_DEFAULT, &illuminance);
     twr_radio_pub_humidity(TWR_RADIO_PUB_CHANNEL_R3_I2C0_ADDRESS_DEFAULT, &humidity);
     twr_radio_pub_temperature(TWR_RADIO_PUB_CHANNEL_R1_I2C0_ADDRESS_DEFAULT, &temperature);
     twr_radio_pub_battery(&voltage);
     twr_radio_pub_string("cvcxvcx","sdfsd");
   
}

void lcd_event_handler(twr_module_lcd_event_t event, void *param)
{
    (void) param;

    if (event == TWR_MODULE_LCD_EVENT_LEFT_CLICK)
    {
        twr_module_lcd_off();
    }
    else if (event == TWR_MODULE_LCD_EVENT_RIGHT_CLICK)
    {
        //twr_gfx_draw_string(pgfx, 10, 80, "RightButt", true);
        /*//Skuska prenosu dat o max velkosti 12B
        uint8_t buffer[12];
        buffer[0] = 0x00;
        buffer[1] = 0x01;
        buffer[2] = 0x02;
        buffer[3] = 0x03;
        buffer[4] = 0x04;
        buffer[5] = 0x05;
        buffer[6] = 0x06;
        buffer[7] = 0x07;
        buffer[8] = 0x08;
        buffer[9] = 0x09;
        buffer[10] = 0x10;
        buffer[11] = 0x11;
        if (twr_module_sigfox_send_rf_frame(&sigfox_module, buffer, sizeof(buffer))) 
        {
            twr_led_set_mode(&led, TWR_LED_MODE_ON);
        } 
        else 
        {
            twr_led_set_mode(&led, TWR_LED_MODE_BLINK);
        }
        */
       twr_module_lcd_on();
    }
    else if (event == TWR_MODULE_LCD_EVENT_BOTH_HOLD)
    {
        //twr_gfx_draw_string(pgfx, 10, 80, "BothButt", true);
    }
}

void sigfox_module_event_handler(bc_module_sigfox_t *self, bc_module_sigfox_event_t event, void *event_param)
{
    (void) self;
    (void) event_param;
    if (event == TWR_MODULE_SIGFOX_EVENT_SEND_RF_FRAME_START)
    {
        twr_led_set_mode(&led, TWR_LED_MODE_ON);
    }
    else if (event == TWR_MODULE_SIGFOX_EVENT_SEND_RF_FRAME_DONE)
    {
        twr_led_set_mode(&led, TWR_LED_MODE_OFF);
    }
    else if (event == TWR_MODULE_SIGFOX_EVENT_ERROR)
    {
        twr_led_set_mode(&led, TWR_LED_MODE_BLINK);
    }
}



// Application initialization function which is called once after boot
void application_init(void)
{
    // Initialize logging
    twr_log_init(TWR_LOG_LEVEL_DUMP, TWR_LOG_TIMESTAMP_ABS);

    // Initialize Battery modul
    twr_module_battery_init();

    // Initialize LED
    twr_led_init(&led, TWR_GPIO_LED, false, 0);
    //twr_led_pulse(&led, 2000);

    // Initialize button on Core modul
    //twr_button_init(&button, TWR_GPIO_BUTTON, TWR_GPIO_PULL_DOWN, 0);
    //twr_button_set_event_handler(&button, button_event_handler, NULL);

    //nepouzijem meranie teploty z Core senzoru 
    // Initialize thermometer on core module
    //twr_tmp112_init(&tmp112, TWR_I2C_I2C0, 0x49);//adresa zo schemy Core modulu
    // after measurement is called tmp112_event_handler
    //twr_tmp112_set_event_handler(&tmp112, tmp112_event_handler, NULL);
    // automatically measure the temperature every 10 seconds
    //twr_tmp112_set_update_interval(&tmp112, 10000);

    // Initialize radio
    twr_radio_init(TWR_RADIO_MODE_NODE_SLEEPING);
    // Send radio pairing request
    twr_radio_pairing_request("Visegrad project Slovakia", _NEWLIB_VERSION);
    //other teams Hungary ... in order to see difference in Playground 


    
    //initialize LCD
    //twr_module_lcd_init();
    //twr_module_lcd_set_font(&twr_font_ubuntu_15);
    
    //initialize LCD modul nove riesenie
    twr_module_lcd_init();
    twr_module_lcd_set_event_handler(lcd_event_handler, NULL);//kvoli tlacitkam na LCD
    pgfx = twr_module_lcd_get_gfx();
    twr_gfx_set_font(pgfx, &twr_font_ubuntu_15);
    twr_module_lcd_clear();
    //twr_gfx_draw_string(pgfx, 50, 50, "Hello world", true);
        
    //initialize Climate modul
    bc_module_climate_init();
    bc_module_climate_set_event_handler(climate_module_event_handler, NULL);
    bc_module_climate_set_update_interval_all_sensors(SENSOR_UPDATE_INTERVAL_SECONDS * 1000); //konstanta z #define je 10 takze 10 s spolu
    bc_module_climate_measure_all_sensors();

    //Initialise Sigfox modul
    twr_module_sigfox_init(&sigfox_module, TWR_MODULE_SIGFOX_REVISION_R2);
    twr_module_sigfox_set_event_handler(&sigfox_module, sigfox_module_event_handler, NULL);
}

//Work with scheduler
//chcem spustit tuto funkciu po nejakom case
static void disableLCD(void* param) {
    (void) param;
    twr_module_lcd_off();
}

// Application task function (optional) which is called peridically if scheduled
void application_task(void)
{
    static int counter = 0;

    // Log task run and increment counter
    twr_log_debug("APP: Task run (count: %d)", ++counter);//asi pretypuje cokolvek na int

    // Battery check
    //twr_module_battery_measure();
    //twr_gfx_clear(pgfx);
    //float voltage = 0.0;
    //twr_module_battery_get_voltage(&voltage);
    //static char volt[25];
    //sprintf(volt, "Voltage: %.1f V", voltage);

    //int charge_percentage = -1;
    //twr_module_battery_get_charge_level(&charge_percentage);
    //static char charge[25];
    //sprintf(charge, "Charge: %d %c", charge_percentage, 37);//%d %c prve neviem, druhe pise znak percent, ale musi byt 37, 38 je napr. ampersand

    //twr_gfx_draw_string(pgfx,10, 95, volt, true);
    //twr_gfx_draw_string(pgfx,10, 110, charge, true);

    //twr_module_lcd_update();

    //twr_scheduler_plan_current_relative(500);
    //twr_scheduler_plan_current_from_now(1000);
    //twr_scheduler_register(disableLCD, NULL, twr_tick_get() + 5000);//zavola mi disableLCD raz po 5 s od pripojenia

    uint8_t buffer[12];
    buffer[0] = 0x00;//0 SK, 1 Ukr, 2 Poland, 3 Czech, 4 Hungary - Second number is order of sensor in range 0-15
    //0x43 is Hungarian fourth sensor 
    //buffer[1] = 0x01;
    
    buffer[1] =  temperature_to_hexa(temperature);
    //twr_log_debug("Temperature real: %.2f", temperature);
    //twr_log_debug("Buffer[1]) decimal from function: %d", temperature_to_hexa(temperature));
    
    buffer[2] =  humidity_to_hexa(humidity);
    //twr_log_debug("Himidity real: %.2f", humidity);
    //twr_log_debug("Buffer[2]) decimal from function: %d", humidity_to_hexa(humidity));
    
    buffer[3] = illumination_to_hexa(illuminance);
    //twr_log_debug("Illumination real: %.2f", illuminance); 
    //twr_log_debug("Buffer[3]) decimal from function: %d", illumination_to_hexa(illuminance));
    
    buffer[4] = illumination_to_hexa(illuminance)>>8;
    //twr_log_debug("Illumination real: %.2f", illuminance);
    //twr_log_debug("Buffer[4]) decimal from function: %d", illumination_to_hexa(illuminance) >> 8);
   
    buffer[5] = pressure_to_hexa(pressure);
    //twr_log_debug("Air pressure real: %.2f", pressure);
    //twr_log_debug("Buffer[5]) decimal from function: %d", pressure_to_hexa(pressure));
    //twr_log_debug("Buffer[5]): %x", buffer[5]);

    buffer[6] = pressure_to_hexa(pressure)>>8;
    //twr_log_debug("Air pressure real: %.2f", pressure);
    //twr_log_debug("Buffer[5]) decimal from function: %d", pressure_to_hexa(pressure));
    //twr_log_debug("Buffer[5]): %x", buffer[5]);

    buffer[7] = battery_voltage_to_hexa(voltage);
    //twr_log_debug("Battery voltage real: %.2f", voltage);
    //twr_log_debug("Buffer[6]) decimal from function: %d", battery_voltage_to_hexa(voltage));

    buffer[8] = battery_charge_level_to_hexa(charge_percentage);
    //twr_log_debug("Battery charge real: %d", charge_percentage);

    buffer[9] = 0x00;
    buffer[10] = 0x00;
    buffer[11] = 0x00;
    twr_log_debug("Buffer[7]) decimal from function: %d", battery_charge_level_to_hexa(charge_percentage));

    //twr_log_debug("Buffer: %x %x %x %x %x %x %x %x %x %x %x %x", buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5],buffer[6],buffer[7],buffer[8],buffer[9],buffer[10],buffer[11]);
    bc_scheduler_plan_current_relative(10000);
    twr_radio_pub_buffer(buffer,12);
    
/*
    if (twr_module_sigfox_send_rf_frame(&sigfox_module, buffer, sizeof(buffer)))
    {
        twr_scheduler_plan_current_relative(REGULAR_REPORT_SECONDS * 1000);
         twr_log_debug("Buffer: %x %x %x %x %x %x %x %x %x %x %x %x", buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5],buffer[6],buffer[7],buffer[8],buffer[9],buffer[10],buffer[11]);
    }
    else
    {
        twr_scheduler_plan_current_relative(1000);
    }
*/
}
