 // Elapsed Time Control
 elapsedMillis timeElapsed;
 elapsedMillis resendTimer;
+elapsedMillis ignoranceTimer;
 
 /**
  *  Setup

  // PROCEED THE ENVIRONMENT CONTROL
  // =================================================================================================================================

  // delay before next command and sample the data again
  sht3x.readSample();
  delay(2000);
  
  // read SHT3x again
  currentTemp = sht3x.getTemperature();
  currentRh = sht3x.getHumidity();

  // filter out incorrect SHT3x reading
  if(currentTemp > -100 && currentRh >= 0)
  {
    // Calculate Heat Index
    float curHeatIndex = heatIndex((double) currentTemp, (double) currentRh);
    
    // the following conditions will ignore the ON-OFF timer
    if(
       (isOn == MODE_OFF && ((float) curHeatIndex) >= ((float) HEAT_INDEX_TOO_HIGH)) ||                   // heat index too high
       (isOn != MODE_OFF && ((float) currentTemp) <= ((float) TEMP_TOO_LOW)) ||                           // temperature too low
       (isOn == MODE_COOLING && ((float) currentTemp) < ((float) TEMP_LOW) && currentRh > RH_LOW) ||      // cooling -> dehumidifier
       (isOn == MODE_DEHUMIDIFIER &&                                                                      // dehumidifier -> cooling
        ((((float) currentTemp) > ((float) TEMP_LOW) && currentRh < RH_LOW) ||
         ((float) curHeatIndex >= (float) HEAT_INDEX_HIGH)))
      )
    {
      // ambient condition exceeds the limit, skip the KEEP_ONOFF_TIMER
      timeElapsed = (long) KEEP_ONOFF_TIMER * (long) 60000;
    }

    // once the air conditioning mode is switched, keep the state for a certain amount of time
    // otherwise, it will be annoyed
    unsigned int timeElaspedInMinutes = timeElapsed / (long) 60000;
    if(timeElaspedInMinutes >= KEEP_ONOFF_TIMER)
    {
      // determine the air conditioning state
      if(isOn == MODE_OFF)
      {
        // assume current air conditioning is OFF
        // heat index (temperature) priority
        if((float) curHeatIndex >= (float) HEAT_INDEX_HIGH)
        {
          // I guess this is a Winter Mode
          if(((float) currentTemp) > ((float) TEMP_HIGH))
          {
            daikin_cooling_on();
            resend = 0;       // reset the sending count
            timeElapsed = 0;  // reset mode-switch timer
          }
          else
          {
            daikin_dehumidifier_on();
            resend = 0;       // reset the sending count
            timeElapsed = 0;  // reset mode-switch timer
          }
        }
      }
      else if(isOn == MODE_COOLING)
      {
        // assume current air condition in running cooling
        if(((float) currentTemp) < ((float) TEMP_LOW) && currentRh <= RH_LOW)
        {
          daikin_all_off();
          resend = 0;       // reset the sending count
          timeElapsed = 0;  // reset mode-switch timer
        }
        else if(((float) currentTemp) < ((float) TEMP_LOW) && currentRh > RH_LOW)
        {
          daikin_dehumidifier_on();
          resend = 0;       // reset the sending count
          timeElapsed = 0;  // reset mode-switch timer
        }
      }
      else // MODE_DEHUMIDIFIER
      {
        // assume current air conditioning is running dehumidifier
        if((((float) currentTemp) <= ((float) TEMP_LOW) && currentRh < RH_LOW) ||       // meet both criterias
           (((float) currentTemp) <= ((float) TEMP_TOO_LOW)))                           // humidifier goes too far, stop the air conditioning temperarily
        {
          daikin_all_off();
          resend = 0;       // reset the sending count
          timeElapsed = 0;  // reset mode-switch timer
        }
        else if((((float) currentTemp) > ((float) TEMP_LOW) && currentRh < RH_LOW) ||   // humidity reaches low but temperature is higher than low
                ((float) currentTemp > (float) TEMP_HIGH))                              // if high temp reached, switch to cooling
        {
          daikin_cooling_on();
          resend = 0;       // reset the sending count
          timeElapsed = 0;  // reset mode-switch timer
        }
      }
    } // end if(timeElaspedInMinutes >= KEEP_ONOFF_TIMER)
  } // end if(currentTemp > -100 ...)

  // =================================================================================================================================


  // reset the air conditioning control
  isOn = MODE_OFF;
  resendTimer = 0;
  ignoranceTimer = 0;
  stopAirCondRunning = false;

  // needs no UART echo
  String qmoteCmd = "ATE0\r\n";
