/*  ARMOSY-2 - ovládanie výstupov pomocou SMS
 *   Autor: Vladimír Rybár
 *   Dátum: 04.05.2019
 *   v1.5 - 
 *   Popis: 
       Namapovanie vstupov a výstupov
       ovládanie SIM800L
       Aktivovanie výstupov podľa príkazov
       ADC meranie tlaku
       pridanie RTC
       Watchdog
       Prerusenie elektromer
       SD-karta, zatial bez loggeru
       Finalna grafika
       WIFI - uspanie
       
 */

 // LIBRARY
 #include <UTFT.h>    // driver k UTFT
 #include <Wire.h>    // Library I2C
 #include <MCP3424.h> // Library ADC MCP3424.h 8 bit
 #include "Sodaq_DS3231.h"  // DS3231 RTC
 #include <eepromi2c.h>     // EEPROM
 #include <OneWire.h>
 #include <DallasTemperature.h>
 #include <SPI.h>       //SPI driver
 #include <SD.h>        // SD Card
 
 // DECLARATION
       // Watchdog
       int watchdogTime = 8000;
       void watchdogSetup(void) {};     
       
       // UTFT - ILI9341
       UTFT myGLCD(ILI9341_8,38,39,40,41);    // ILI9341, RS, WR, CS, REST
       extern uint8_t BigFont[];              // UTFT BigFont
       extern uint8_t SmallFont[];            // UTFT SmallFont

       // MCP3424
       MCP3424 adc_mcp(0x6B);   // Adress 107 DEC       
       double value_adc;    // Value ADC
       float volt;          //volt in 
       float pressure;

       // EEPROM Area
                  
       float countkwh;
        // INTERRUPT
       int pocitadlo=0;  // pocitadlo pulzov
       
       // Variables
       #define IN_1 54                        // Terminal 1,2
       #define IN_2 55                        // Terminal 3,4
       #define IN_3 56                        // Terminal 5,6
       #define IN_4 57                        // Terminal 7,8
       #define IN_5 58                        // Terminal 9,10
       #define IN_6 59                        // Terminal 11,12
       #define IN_7 60                        // Terminal 13,14
       #define IN_8 61                        // Terminal 15, 16
       #define ACS712_1 62                    // ACS712 I1 Terminal 17,18
       #define ACS712_2 63                    // ACS712 I2 Terminal 19,20
       #define A10 64                         // System Voltage 3.3V
       #define A11 65                         // System Voltage 5V
       #define LED_GREEN 12                   // LED GREEN
       #define LED_RED 68                     // LED RED
       #define BUTT_H 47                      // Buttons High
       #define BUTT_L 48                      // Buttons Low
       #define DS18B20 5                      // DS18B20 1W terminal 60
       byte RELE_1 = 30;                      // Relay 1, terminal 21,22,23
       byte RELE_2 = 31;                      // Relay 2, terminal 24,25,26
       byte RELE_3 = 32;                      // Relay 3, terminal 27,28,29
       byte RELE_4 = 33;                      // Relay 4, terminal 30,31,32
       byte OUT_1 = 6;                        // Terminal 33,34, PWM
       byte OUT_2 = 7;                        // Terminal 35,36, PWM
       byte OUT_3 = 8;                        // Terminal 37,38, PWM
       byte OUT_4 = 9;                        // Terminal 39,40, PWM
       byte OUT_5 = 34;                       // Terminal 41,42
       byte OUT_6 = 35;                       // Terminal 43,44
       byte OUT_7 = 36;                       // Terminal 45,46
       byte OUT_8 = 37;                       // Terminal 47,48
       byte BEEP = 13;                        // Beep Tone
       bool b_BUTT_H = 1;                     // State Button H
       bool b_BUTT_L = 1;                     // State Button L
       
       // Universal I/O
       #define U_1 49 // Terminal 49
       #define U_2 50 // Terminal 50
       #define U_3 51 // Terminal 51
       #define U_4 52 // Terminal 52
       #define U_5 66 // Terminal 53
       #define U_6 69 // Terminal 54
       #define U_7 11 // Terminal 55
       #define U_8 2 // Terminal 56

       // Teplota
       OneWire ourWire(DS18B20);
       DallasTemperature sensors(&ourWire);
      // char sensorPrintout[1];              // Char array to print to the screen
      // float TMP;
       float teplota;
       
       // GSM
       #define Serial SerialUSB     // USB - PC
       #define SIM800 Serial2       // SIM800 Serial2 RX2/TX2    
    //   #define Wifi Serial1;         // Wifi ESP8266 Serial1
       #define PC Serial            // PC Serial

       
       #define GSMRing 70           // SIM800 - Ring pin 
       #define GSMReset 71          // SIM800 - RST pin
       String GSMsignal;

        // Draw macros
        #define X1 120
        #define Y1 50
        #define R1 7
        #define X2 140
        #define Y2 75
        #define X3 220
        #define Y3 100      

        // Možné telefónne čísla, commandy, odpovede
        #define LENGTH_APHONEBOOK 2
        #define MAX_APHONEBOOK 14
        #define LENGTH_PHONEBOOK 3
        #define MAX_PHONEBOOK 14
        #define LENGTH_COMMANDS 6
        #define MAX_COMMANDS 10
        #define LENGTH_ANSWERS 9
        #define MAX_ANSWERS 160
        #define LENGTH_EANSWERS 8
        #define MAX_EANSWERS 50

        // 

       char Aphonenumbers[LENGTH_APHONEBOOK][MAX_APHONEBOOK]={
       {"+421902327555"},
       {""},
       };
       char phonenumbers[LENGTH_PHONEBOOK][MAX_PHONEBOOK]={
       {""},
       {"+421904008627"},
       };
       char commands[LENGTH_COMMANDS][MAX_COMMANDS]={
        {""},
        {"start"}, 
        {"stop"}, 
        {"info"},
        {"admin on"},
        {"admin off"},
        };
       char answers[LENGTH_ANSWERS][MAX_ANSWERS]={
        {"Posli SMS s textom 'info'"}, 
        {"Spustam cerpadlo"}, 
        {"Vypinam cerpadlo"}, 
        {"Mozne prikazy: Start - spustenie cerpadla, Stop - vypnutie cerpadla, Admin on/off - prioritny rezim"},    
        {"Pusteny administratorsky rezim"}, 
        {"Vypnuty administratorsky rezim"},   
        {"Momentalne nemate pravo ovladat cerpadlo"},  
        {"Nemate pravo ovladat administratorsky rezim"}
        };
        
        char eanswers[LENGTH_EANSWERS][MAX_EANSWERS]={
        {""}, 
        {""},
        {"Nizka hladina vody v potoku. Cerpadlo vypnute."}, 
        {"Vysoka hladina vody v potoku. Cerpadlo Vypnute"}, 
        {"Porucha napajania 400V"},    
        {"Porucha napajania 24V"}, 
        {"Vybite baterie"},   
        {""},  
        };

      bool state_priority = false;
      struct incSMS {bool flag; String PhoneNumber;  String SMStext;};
      incSMS info;
    
    // DECLARATION RTC
   char Date[11]; 
   char Time[14];               // Area Time
   #define RTC_ADDRESS 0x68     // Address RTC


   

   // Inputstate

   bool inputstatesold[10]={false,false,false,false,false,false,false,false,false,false};
   
void setup() 
{
  // Watchdog Timer
   watchdogEnable(watchdogTime);



    
  // UTFT - init
  myGLCD.InitLCD();     // Initialization LCD
  myGLCD.clrScr();        // Clear Screen
  myGLCD.fillScr(VGA_WHITE); // VGA Background Transparency
  myGLCD.setColor(0, 0, 0); // Black Fonds
  myGLCD.setBackColor(255, 255, 255); // White Background
  myGLCD.setFont(BigFont); // Select Font
  myGLCD.print("Inicializacia...",CENTER,10);
  myGLCD.setFont(SmallFont); // Select Font

    // vypnutie WIFI - deep sleep
  Serial1.begin(115200);

  WIFIInit(); 

  Serial1.end();
  
  // 1 WIRE
  sensors.begin();
  sensors.setResolution(10);
  
  // I2C
  Wire.begin();     //I2C start

  // Prvotný init, synchronizácia počítadla v EEPROM s ciferníkom elektormeru
           float count_init = 0;  // počiatočný stav elektromeru
         eeWrite(0, count_init);       

  // SD card
    myGLCD.setFont(SmallFont);
    myGLCD.print("Inicializacia SD karty  ...",20,65);
    delay(500);
    if(!SD.begin(4)){
      myGLCD.print("Inicializacia neuspesna",20,80);
      return;
    }
      myGLCD.print("Inicializacia uspesna",20,80);  
            delay(500);
  // RTC
  rtc.begin();
  
  // ADC MCP3424
  adc_mcp.generalCall(GC_RESET);
  adc_mcp.creg[CH1].bits = { GAINx1, SR16B, CONTINUOUS, CH1, 1};  //Gain, Resolution 12,14,16,18 bits, Type Conv, Channel
  
  // INPUT
  pinMode(IN_1, INPUT_PULLUP); // ON pull-up
  pinMode(IN_2, INPUT_PULLUP); // ON pull-up
  pinMode(IN_3, INPUT_PULLUP); // ON pull-up
  pinMode(IN_4, INPUT_PULLUP); // ON pull-up
  pinMode(IN_5, INPUT_PULLUP); // ON pull-up
  pinMode(IN_6, INPUT_PULLUP); // ON pull-up
  pinMode(IN_7, INPUT_PULLUP); // ON pull-up
  pinMode(IN_8, INPUT_PULLUP); // ON pull-up
  pinMode(BUTT_H, INPUT_PULLUP); // ON pull-up
  pinMode(BUTT_L, INPUT_PULLUP); // ON pull-up

  attachInterrupt(digitalPinToInterrupt(IN_8),blink, RISING);
  
  //  OUTPUT
  pinMode(LED_RED, OUTPUT);
  pinMode(LED_GREEN, OUTPUT);
  pinMode(RELE_1, OUTPUT);
  pinMode(RELE_2, OUTPUT);
  pinMode(RELE_3, OUTPUT);
  pinMode(RELE_4, OUTPUT);
  pinMode(OUT_1, OUTPUT);
  pinMode(OUT_2, OUTPUT);
  pinMode(OUT_3, OUTPUT);
  pinMode(OUT_4, OUTPUT);
  pinMode(OUT_5, OUTPUT);
  pinMode(OUT_6, OUTPUT);
  pinMode(OUT_7, OUTPUT);
  pinMode(OUT_8, OUTPUT);
  pinMode(BEEP, OUTPUT);
  digitalWrite(LED_GREEN, HIGH);
  digitalWrite(LED_RED, HIGH);
  digitalWrite(RELE_1, LOW);
  digitalWrite(RELE_2, LOW);
  digitalWrite(RELE_3, LOW);
  digitalWrite(RELE_4, LOW);
  digitalWrite(OUT_1, HIGH);
  digitalWrite(OUT_2, HIGH);
  digitalWrite(OUT_3, HIGH);
  digitalWrite(OUT_4, HIGH);
  digitalWrite(OUT_5, HIGH);
  digitalWrite(OUT_6, HIGH);
  digitalWrite(OUT_7, HIGH);
  digitalWrite(OUT_8, HIGH);
  digitalWrite(BEEP, HIGH);

//  inputstatesold[0]=digitalRead(IN_1);
//  inputstatesold[7]=digitalRead(IN_8);
//  

   // SIM800 - parameters RX/TX, open connection
  PC.begin(115200);
  SIM800.begin(115200);
  watchdogReset();
  restartSIMHW();
  SIM800Init();
  myGLCD.setFont(BigFont);
  myGLCD.print("Vsetko OK", 20, 200);
  delay(500);
 
  // UTFT init
  myGLCD.clrScr();
   myGLCD.fillScr(VGA_WHITE); // VGA Background Transparency
  myGLCD.setColor(0, 0, 0); // Black Fonds
  myGLCD.setBackColor(255, 255, 255); // White Background
  myGLCD.setFont(BigFont); 
  myGLCD.print("Ovladanie cerpadla", CENTER, 10);
 // myGLCD.print("v1.3", CENTER, 220);
  myGLCD.setFont(SmallFont); // Select Font
      
    myGLCD.setColor(0,0,0);
    myGLCD.print("400V",70,45);
    myGLCD.print("24V",150,45);
    myGLCD.print("BAT",220,45);
    myGLCD.setColor(0,0,0);
    myGLCD.drawCircle(X1,Y1,R1);
    myGLCD.drawCircle(X1+70,Y1,R1);
    myGLCD.drawCircle(X1+140,Y1,R1);

    myGLCD.print("Nizka hladina",20,70);
    myGLCD.print("Vysoka hladina",170,70);
    myGLCD.drawCircle(X2,Y2,R1);
    myGLCD.drawCircle(X2+155,Y2,R1);

    myGLCD.print("SMS stop",20,95);
    myGLCD.print("Admin rezim",170,95);
    myGLCD.drawCircle(X2,Y3,R1);
    myGLCD.drawCircle(X2+155,Y3,R1);



    myGLCD.setFont(BigFont);
    myGLCD.print("Tlak:",20,130);
    myGLCD.print("bar",200,130);

    myGLCD.print("Teplota:",20,170);
 
       
                     
}

void loop() 
{
  bool errorfix=false;
  bool inputstates[10];
  int Answer_index;
  watchdogReset();

  //wakeupscreen = digitalRead(BUTT_H);
  inputstates[0]=!digitalRead(IN_1);
  inputstates[1]=!digitalRead(IN_2);
  inputstates[2]=!digitalRead(IN_3);
  inputstates[3]=!digitalRead(IN_4);
  inputstates[4]=!digitalRead(IN_5);
  inputstates[5]=!digitalRead(IN_6);
  inputstates[6]=!digitalRead(IN_7);
  inputstates[7]=!digitalRead(IN_8);


  

      // Temperature
          sensors.requestTemperatures();
          teplota = sensors.getTempCByIndex(0);
   
         
      // stav elektromeru z EEPROM
         eeRead(0 , countkwh);
         delay(1);       
         if(pocitadlo>=40)
         {
            detachInterrupt(digitalPinToInterrupt(IN_8));
            pocitadlo = 0;
            countkwh += 0.1;
            attachInterrupt(digitalPinToInterrupt(IN_8),blink, RISING);
         }
  

  info = checkSMS();
//  PC.println(info.flag);
//  PC.println(info.PhoneNumber);
//  PC.println(info.SMStext);

  if(info.flag)
  {
    Answer_index =SMSparser(info.PhoneNumber,info.SMStext);
       if(Answer_index !=20) 
       {
        sendSMS(info.PhoneNumber,answers[Answer_index]);  watchdogReset();
    if(Answer_index == 1) inputstates[8]= false;
    if(Answer_index == 2) inputstates[8]= true;
    if(Answer_index == 4) inputstates[9]= true;
    if(Answer_index == 5) inputstates[9]= false;
       }
  }
  else
  {
   inputstates[8] = inputstatesold[8];
   inputstates[9] = inputstatesold[9];
  }

  
  // Načítanie tlaku
  ConvStatus Xerr = adc_mcp.read(CH1, value_adc);
  volt = value_adc * 5; 
  if(volt <= 2.000) volt=2.000;
  pressure = 0.75*volt - 1.50;  //4mA - 0bar, 20mA - 6 bar

  
  // Nacitanie casu z obvodu RTC
  DateTime now = rtc.now();   // get the current date-time
  sprintf(Date,"%02d.%02d.%04d",now.date(),now.month(),now.year());
  sprintf(Time,"%02d:%02d:%02d",now.hour()+1,now.minute(),now.second());  // convert to Time


  

//if(inputstates[0]!=inputstatesold[0] && inputstates[0] ) zapis do loggeru minimalna hladina; else zapis maximalna hladina ;;
//if(inputstates[7]!=inputstatesold[7] && inputstates[7] ) zapis do loggeru cerpadlo on; else zapis do loggeru cerpadlo off ;

  
for(int i=2; i<7;i++)
{
  if(inputstates[i]!=inputstatesold[i] && inputstates[i]) 
  { 
    sendSMS(Aphonenumbers[0],eanswers[i]);
  }
  if(inputstates[i]!=inputstatesold[i] && !inputstates[i]) 
   errorfix=true;
}
if(errorfix)  sendSMS(Aphonenumbers[0],"Vsetky poruchy odstranene.");

   updateDisplay(inputstates); 
   
      for(int i=0;i<10;i++)
    {
        inputstatesold[i]=inputstates[i];
    }

     

}

void WIFIInit()
{
    watchdogReset();
   while (sendwifiATcommand("AT","OK",2000) == 0);       // Ping SIM800L
    myGLCD.print("Wifi modul dostupny...", 20,35);
    delay(500);
   while (sendwifiATcommand("AT+SLEEP=1","OK",200) == 0); 
   myGLCD.print("Wifi modul uspesne uspany...", 20,50);
   delay(500);
}

void SIM800Init()     // inicialization SIM800- network registration
{
 // while (PC.available() > 0) PC.read();
 // PC.println F("****************************************");
  while (sendATcommand("AT","OK",2000) == 0);       // Ping SIM800L
  myGLCD.print("SIM800 modul dostupny!",20,95);
   delay(500);
     watchdogReset();
  //PC.println F("SIM800 modul dostupny!");
  //otestuj registraci do site
  while ( (sendATcommand("AT+CREG?", "+CREG: 0,1", 500) || sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 );      // zaregistrovanie do domácej siete +CREG:0,1  alebo roaming +CREG:0,5 . 
 // while (PC.available() > 0) PC.read();
 // PC.println F("SIM800 registrovan do site!");
   watchdogReset();
  myGLCD.print("SIM800 zaregistrovany v sieti!",20,110);
   delay(500);
  //nastaveni parametru pro obdrzeni casu ze site
  while( sendATcommand("AT+CLTS=1", "OK", 500) == 0 );          // Local Timestamp, mode 1 
  while( sendATcommand("AT+CENG=3", "OK", 500) == 0 );          // prepnutie SIM800L do Engeneering mode
 // while (PC.available() > 0) PC.read();
  //PC.print("Casova znacka:");
  //PC.println(timeStamp());  
  myGLCD.print("Cas:",20,125); 
   delay(500);
   myGLCD.print(timeStamp(),60,125); 
   delay(500);   
  //CSQ, pozice 4
    watchdogReset();
  GSMsignal = sendATcommandResponse("AT+CSQ", "+CSQ:", 1000, 3);        // Zistenie sily signálu , 0- bez signálu , 31 - maximum, na SMS potreba aspoň 9.
  
 // PC.println("GSM signal quality:"+GSMsignal);
  myGLCD.print("Kvalita signalu",20,140);
   delay(500);
  myGLCD.print(GSMsignal,160,140);  
   delay(500);
  if (GSMsignal.length()==3) GSMsignal = GSMsignal.substring(1);
  String providerName = sendATcommandResponse("AT+COPS?","+COPS:",1000,20);
  uint8_t tempIndex = providerName.indexOf('"');
  providerName = providerName.substring(tempIndex+1);
  tempIndex = providerName.indexOf('"');
  providerName = providerName.substring(0,tempIndex);
 // PC.println("GSM provider:"+providerName);
  myGLCD.print("Operator:",20,155); 
   delay(500);
  myGLCD.print(providerName,160,155);
   delay(500);
  
  sendATcommand("AT+GSMBUSY=1","OK",500);             // Forbid all incoming calls
  //PC.println("Blokovanie prichadzajucich hovorov: = Uspesne");
   myGLCD.print("Blokovanie hovorov: Uspesne",20,170);
   delay(500);
  sendATcommand("AT+CMGF=1", "OK", 500);        // Nastavenie písania SMS do Text mode 1
  //zakaz indikace SMS
  sendATcommand("AT+CNMI=0,0", "OK",500);       // New SMS Message Indications
  sendATcommand("AT+CLIP=1", "OK", 500);        // Pustenie CLIP
  //smaz vsechny SMSky
  sendATcommand("AT+CMGD=1,4", "OK", 2000);     // Vymazanie SMS
  sendATcommand("AT+CMGD=1", "OK", 2000);       // Vymazanie SMS
 // PC.println F("Zakladni parametry nastaveny!");
}

int8_t sendATcommand(char const* ATcommand, char* expected_answer, unsigned int timeout)
{

  //WDT_Restart(WDT);
  uint8_t x = 0,  answer = 0;
  //char jolo;
  char response[200];
  unsigned long previous;
  watchdogReset();
  memset(response, '\0', 200);    // Initialize the string

  delay(100);

  //clrSIMbuffer();

  SIM800.println(ATcommand);    // Send the AT command


  x = 0;
  previous = millis();

  // this loop waits for the answer
  do
  {
    //WDT_Restart(WDT);
    if (SIM800.available() != 0) {
      // if there are data in the UART input buffer, reads it and checks for the asnwer
      response[x] = SIM800.read();
      x++;

      // check if the desired answer  is in the response of the module
      if (strstr(response, expected_answer) != NULL)
      {
        answer = 1;
      }
    }
    // Waits for the asnwer with time out
  }
  while ((answer == 0) && ((millis() - previous) < timeout));

  //clrSIMbuffer();
  return answer;
}


//AT prikaz s ocekavanou odpovedi a zbytkem
String sendATcommandResponse( char* ATcommand, char* expected_answer, unsigned int timeout, unsigned int buf)
{
  //WDT_Restart(WDT);
  uint8_t x = 0,  answer = 0;
  char response[150];
  unsigned long previous;
  String rest;

  memset(response, '\0', 100);    // Initialize the string

  delay(100);

  //clrSIMbuffer();
  SIM800.println(ATcommand);    // Send the AT command


  x = 0;
  previous = millis();
  //WDT_Restart(WDT);
  // this loop waits for the answer
  do
  {
    //WDT_Restart(WDT);
    if (SIM800.available() != 0) {
      // if there are data in the UART input buffer, reads it and checks for the asnwer
      response[x] = SIM800.read();
      x++;
      // check if the desired answer  is in the response of the module
      if (strstr(response, expected_answer) != NULL)
      {
        answer = 1;
      }
    }
    // Waits for the asnwer with time out
  }
  while ((answer == 0) && ((millis() - previous) < timeout));

  //p?e?ti zbytek - max 20 byte
  memset(response, '\0', buf);    // Initialize the string
  delay(100);
  for (x = 0; x < buf; x++) response[x] = SIM800.read();
  //clrSIMbuffer();
  for (x = 0; x < buf; x++) rest += char(response[x]);
  delay(100);
  return rest;
}

int8_t sendwifiATcommand(char const* ATcommand, char* expected_answer, unsigned int timeout)
{

  //WDT_Restart(WDT);
  uint8_t x = 0,  answer = 0;
  //char jolo;
  char response[200];
  unsigned long previous;

  memset(response, '\0', 200);    // Initialize the string

  delay(100);

  //clrSIMbuffer();
    watchdogReset();
  Serial1.println(ATcommand);    // Send the AT command
  //if(strstr(ATcommand,"AT+CMGS=") != NULL) SIM800.println((char)26); // CTRL +Z ukoncovaci znak SMS
  //WDT_Restart(WDT);

  x = 0;
  previous = millis();

  // this loop waits for the answer
  do
  {
    //WDT_Restart(WDT);
    if (Serial1.available() != 0) {
      // if there are data in the UART input buffer, reads it and checks for the asnwer
      response[x] = Serial1.read();
      x++;

      // check if the desired answer  is in the response of the module
      if (strstr(response, expected_answer) != NULL)
      {
        answer = 1;
      }
    }
    // Waits for the asnwer with time out
  }
  while ((answer == 0) && ((millis() - previous) < timeout));

  //clrSIMbuffer();
  return answer;
}
//Receive SMS
struct incSMS checkSMS()
{
  incSMS temp;
  temp.flag=false;
  char g;
  String gcmd;
  uint8_t gindex;

  clrSIMbuffer();
  
  SIM800.println("AT+CMGR=1");
  delay(100);
  //potla?en? echa
  while(SIM800.available()>0)
  {
    g=SIM800.read();
    gcmd += g;
    if (g=='\n')
    {
      gcmd = "";
      break;
    }
  }

  //na?ti prvn? ??dek odpov?di
  while(SIM800.available()>0)
  {
    g=SIM800.read();
    gcmd += g;
    if (g=='\n')
    {
    //  PC.println("Navrat"+gcmd);
      if (gcmd.substring(0,2)=="OK") break;
      if(gcmd.substring(0,5)=="+CMGR")
      {
        //Serial.println(gcmd);
        temp.flag = true;
        PC.println("Nova SMSka!!!!");
        digitalWrite(BEEP,LOW);
        //prvni + "+CMGR"
        gindex = gcmd.indexOf('+');
        if(gindex < 0) break;
        //odsekni prvn? +
        gcmd = gcmd.substring(gindex+1);
        //Serial.println(gcmd);
        //dal?? + - obsahuje ??slo odes?latele
        gindex = gcmd.indexOf('+');
        temp.PhoneNumber = gcmd.substring(gindex,gindex+13);
        PC.println("Od:" + temp.PhoneNumber);
        //precti obsah SMS
        gcmd = "";
        delay(50);
        digitalWrite(BEEP,HIGH);
        while (SIM800.available()>0)
        {
          g=SIM800.read();
          gcmd += g;
          if (g=='\n')
          {
            gcmd = gcmd.substring(0,gcmd.length()-2);
            temp.SMStext=gcmd;
            PC.println("Obsah SMS:" +  temp.SMStext);
            gcmd = "";
            sendATcommand("AT+CMGD=1", "OK", 1000);
            sendATcommand("AT+CMGD=1,4", "OK", 1000);
            PC.println("SMS smazana z pameti.");
            return temp;
          }
        }
        gcmd="";
        sendATcommand("AT+CMGD=1", "OK", 1000);
        sendATcommand("AT+CMGD=1,4", "OK", 1000);        
//        sendATcommandResponse
      }
      temp.PhoneNumber = "";
      temp.SMStext ="";
    }
  }
   return temp;
}

//Send SMS
void sendSMS(String number, String sms)
{
  String temp;
  PC.println("SMS pre:"+number);
  PC.println("Obsah:"+sms);
  delay(200);
  clrSIMbuffer();
    temp = "AT+CMGS=\""+number+"\"";   
   sendATcommand(temp.c_str(),">",1000);
    sendATcommand(sms.c_str(),"",1000);
   sendATcommand("\x1A","OK",60000);
  
  delay(100);
  clrSIMbuffer();
  SIM800.println();
  delay(100);
  sendATcommand("AT+CMGD=1", "OK", 5000);
  sendATcommand("AT+CMGD=1,4", "OK", 5000);
  delay(500);
  clrSIMbuffer();
  PC.println("SMS odeslana!");
}

int SMSparser(String number, String command)
// vrati cislo zhodujuceho sa commandu, v pripade neznameho cisla ho posle do <>
{ 
  bool prioritynumber= false;
  bool numbermatch = false;
  bool commandmatch = false;
  command.toLowerCase();

   for(int i=0; i<LENGTH_APHONEBOOK ; i++)
  {
    if(number==Aphonenumbers[i]) prioritynumber=true;
  } 
  for(int i=0; i<LENGTH_PHONEBOOK ; i++){
    if(number==phonenumbers[i]) numbermatch=true;
  }
    for(int i=0; i<LENGTH_COMMANDS ; i++){
    if(command==commands[i]) commandmatch=true;
  }
  if(!numbermatch && !prioritynumber) return 20;
  if(!commandmatch) return 0;

    if (command == commands[1]) 
    {
      if(!prioritynumber && state_priority) return 6;
      digitalWrite(RELE_1,LOW);
      return 1;
    }
    if (command == commands[2])
    {
      if(!prioritynumber && state_priority) return 6;
      digitalWrite(RELE_1,HIGH);
      return 2;
    }
     
    if (command == commands[3])
  {
    return 3;
  }
  if (command == commands[4])
  {
    if(prioritynumber){ 
    state_priority = true;
    return 4;}
    else
    return 7;
  }
    if (command == commands[5])
  {
      if(prioritynumber){ 
      state_priority = false;
      return 5;}   
      else
      return 7;    
  }

}



String timeStamp()
{
  String ts="";
   ts = sendATcommandResponse("AT+CCLK?", "+CCLK: \"", 1000, 20);

  //13/11/04,15:23:19+04
  //return (ts.substring(6,8)+"."+ts.substring(3,5)+".20"+ts.substring(0,2)+ts.substring(9,11)+ts.substring(12,14)+ts.substring(15,17));
  return ts;
}
void restartSIMHW()
{
  //HW restart
  digitalWrite(GSMReset,LOW);
  delay(400);
  digitalWrite(GSMReset,HIGH);
  delay(400);
}
void clrSIMbuffer()
{
  while(SIM800.available()>0)
  {
    delay(5);
    SIM800.read();
  }
}


void updateDisplay(bool inputstates[])
{
  myGLCD.setBackColor(VGA_WHITE);
  myGLCD.setColor(0,0,0);
  myGLCD.setFont(BigFont);
  myGLCD.printNumF(teplota,2,180, 170);
  myGLCD.printNumF(pressure,2, 100, 130);
  myGLCD.setFont(SmallFont);
  myGLCD.print(Date,80, 225);
  myGLCD.print(Time,180, 225);
  
  if(inputstates[2]!=inputstatesold[2])
   { if(inputstates[2])
    {
      myGLCD.setColor(255,0,0);
      myGLCD.fillCircle(X2,Y2,R1-1);
    }
    else
    {
      myGLCD.setColor(255,255,255);
      myGLCD.fillCircle(X2,Y2,R1-1);
    }
   }
   
  if(inputstates[3]!=inputstatesold[3])
   { if(inputstates[3])
    {
      myGLCD.setColor(255,0,0);
      myGLCD.fillCircle(X2+155,Y2,R1-1);
    }
    else
    {
      myGLCD.setColor(255,255,255);
      myGLCD.fillCircle(X2+155,Y2,R1-1);
    }
   }
  if(inputstates[4]!=inputstatesold[4])
   { if(inputstates[4])
    {
      myGLCD.setColor(255,0,0);
      myGLCD.fillCircle(X1,Y1,R1-1);
    }
    else
    {
      myGLCD.setColor(255,255,255);
      myGLCD.fillCircle(X1,Y1,R1-1);
    }
   }
     if(inputstates[5]!=inputstatesold[5])
   { if(inputstates[5])
    {
      myGLCD.setColor(255,0,0);
      myGLCD.fillCircle(X1+70,Y1,R1-1);
    }
    else
    {
      myGLCD.setColor(255,255,255);
      myGLCD.fillCircle(X1+70,Y1,R1-1);
    }
   }  
   if(inputstates[6]!=inputstatesold[6])
   { if(inputstates[6])
    {
      myGLCD.setColor(255,0,0);
      myGLCD.fillCircle(X1+140,Y1,R1-1);
    }
    else
    {
      myGLCD.setColor(255,255,255);
      myGLCD.fillCircle(X1+140,Y1,R1-1);
    }
   }
        if(inputstates[8]!=inputstatesold[8])
   { if(inputstates[8])
    {
      myGLCD.setColor(255,0,0);
      myGLCD.fillCircle(X2,Y3,R1-1);
    }
    else
    {
      myGLCD.setColor(255,255,255);
      myGLCD.fillCircle(X2,Y3,R1-1);
    }
   }  
   if(inputstates[9]!=inputstatesold[9])
   { if(inputstates[9])
    {
      myGLCD.setColor(255,0,0);
      myGLCD.fillCircle(X2+155,Y3,R1-1);
    }
    else
    {
      myGLCD.setColor(255,255,255);
      myGLCD.fillCircle(X2+155,Y3,R1-1);
    }
   }
   
//       if(digitalRead(IN_4)==0)
//  {
//    myGLCD.setColor(0,255,0);
//    myGLCD.fillCircle(X1,Y1,R1-1);
//  }
//  else
//  {
//    myGLCD.setColor(255,0,0);
//    myGLCD.fillCircle(X1,Y1,R1-1);
//  }
//    if(digitalRead(IN_5)==0)
//  {
//    myGLCD.setColor(0,255,0);
//    myGLCD.fillCircle(X1+70,Y1,R1-1);
//  }
//  else
//  {
//    myGLCD.setColor(255,0,0);
//    myGLCD.fillCircle(X1+70,Y1,R1-1);
//  } 
//  if(state_priority)
//    {
//    myGLCD.setColor(0,255,0);
//    myGLCD.fillCircle(X3,Y3,R1-1);
//  }
//  else
//  {
//    myGLCD.setColor(255,0,0);
//    myGLCD.fillCircle(X3,Y3,R1-1);
//  }
}

void blink(void)
{
  pocitadlo++;
}
