// The code below is extracted from my home automation controller - it is unlikely
// you will be able to use it directly, but it should help guide you in decoding
// and assembling data packets for Lennox mini-split air conditioners.


//    ----------------- AIRCO SECTION -----------------
int decode_time(int Byte, int *halfhr) {
  int b1, b2, b4, b8, b16, b32, hr;
  // Displayed times are calculated times + half hr.
  if (Byte&64) *halfhr = 0; else *halfhr = 1; // half-hr time plus half-hr offset
  b16 = Byte&2 ? 16 : 0;
  b8 = Byte&4 ? 8 : 0;
  b4 = Byte&8 ? 4 : 0;
  b2 = Byte&16 ? 2 : 0;
  b1 = Byte&32 ? 1 : 0;
  hr = b16+b8+b4+b2+b1;
  if (Byte&64) hr += 1; // half-hr time plus half-hr offset increments hour
  return hr;
}

int decode_temperature(int Byte2, int Byte5) {
  int b1, b2, b4, b8, b16;
  //assert((Byte2&7) == 6);
  //assert((Byte5&7) == 6);
  b16 = Byte2&8   ? 16 : 0;
  b8  = Byte2&16  ?  8 : 0;
  b4  = Byte2&32  ?  4 : 0;
  b2  = Byte2&64  ?  2 : 0;
  b1  = Byte2&128 ?  1 : 0;
  return b16+b8+b4+b2+b1;
}

int decode_mode(int Byte1, int Byte5) {
  int b1, b2, b4, b8, b16;
  //assert((Byte2&7) == 6);
  //assert((Byte5&7) == 6);
  b4  = Byte1&32  ?  4 : 0;
  b2  = Byte1&64  ?  2 : 0;
  b1  = Byte1&128 ?  1 : 0;
  return b1+b2+b4;
}

int decode_fan(int Byte1, int Byte5) {
  int b1, b2, b4, b8, b16;
  //assert((Byte2&7) == 6);
  //assert((Byte5&7) == 6);
  b4  = Byte1&4   ?  4 : 0;
  b2  = Byte1&8   ?  2 : 0;
  b1  = Byte1&16  ?  1 : 0;
  return b4+b2+b1;
}

int crc1(int code[6]) {
  int i, x = 0xff;
  for (i = 0; i < 5; i++) {
    x = x+code[i];
  }
  return (x^0xff)&255;
}

static long int
  lennox_airco_Follow=0,
  lennox_airco_led = 1,
  lennox_airco_temp = 0,
  lennox_airco_fan = 0,
  lennox_airco_timer_off_half = 0,
  lennox_airco_timer_off = 0,
  lennox_airco_timer_on = 0,
  lennox_airco_timer_on_half = 0,
  lennox_airco_swing = 0,
  lennox_airco_turbo = 0,
  lennox_airco_clean = 0,
  lennox_airco_power = 1,
  lennox_airco_sleep = 0,
  lennox_airco_direct = 0,
  lennox_airco_mode = 0;

// DECODERS:

void decode_lennox(int code[6]) {
  char message[1024];
  int F;
  switch (code[0]) {
  case 0x25:
    load_global("bedroom-lennox.follow", &lennox_airco_Follow); // does not alter Follow if not found.
    //printf("Follow.");
    if (code[4] == 0xCC) {
      int i = code[3]&0x03;
      if (i == 0) {
        //printf("[Follow=OFF]");
        if (lennox_airco_Follow == 1) {
          lennox_airco_Follow = 0;
          save_global("bedroom-lennox.follow", lennox_airco_Follow);
          quicksay("bedroom air conditioner has turned off follow mode");
        }
      } else if (i == 3) {
        //printf("[Follow=ON]");
        if (lennox_airco_Follow == 0) {
          lennox_airco_Follow = 1;
          save_global("bedroom-lennox.follow", lennox_airco_Follow);
          quicksay("bedroom air conditioner has turned on follow mode");
        }
      } else {
        //printf("[Follow=%d]", i);
        sprintf(message, "bedroom air conditioner did something related to follow mode. Mode value is %d", i);
        quicksay(message);
      }
    } else {
      //printf("[Follow??? %02x (%d)]", code[4], code[4]);
      sprintf(message, "bedroom air conditioner did something related to follow mode.  Code is %d", code[4]);
      quicksay(message);
    }
    break;
  case 0x45:
    //printf("Function toggle.");
    switch (code[1]) {
    case 0x10: //printf("[FN=LED]");
      load_global("bedroom-lennox.led", &lennox_airco_led);
      if (lennox_airco_led == 0) {
        lennox_airco_led = 1;
        save_global("bedroom-lennox.led", lennox_airco_led);
        quicksay("bedroom air conditioner turned the L E D on"); break;
      } else {
        lennox_airco_led = 0;
        save_global("bedroom-lennox.led", lennox_airco_led);
        quicksay("bedroom air conditioner turned the L E D off"); break;
      }
    case 0x40: //printf("[FN=SWING]");
      load_global("bedroom-lennox.swing", &lennox_airco_swing);
      if (lennox_airco_swing == 0) {
        lennox_airco_swing = 1;
        save_global("bedroom-lennox.swing", lennox_airco_swing);
        quicksay("bedroom air conditioner turned swing mode on"); break;
      } else {
        lennox_airco_swing = 0;
        save_global("bedroom-lennox.swing", lennox_airco_swing);
        quicksay("bedroom air conditioner turned swing mode off"); break;
      }
    case 0x80: //printf("[FN=DIRECT]");
      load_global("bedroom-lennox.direct", &lennox_airco_direct);
      if (lennox_airco_direct == 0) {
        lennox_airco_direct = 1;
        save_global("bedroom-lennox.direct", lennox_airco_direct);
        quicksay("bedroom air conditioner turned direct mode on"); break;
      } else {
        lennox_airco_direct = 0;
        save_global("bedroom-lennox.direct", lennox_airco_direct);
        quicksay("bedroom air conditioner turned direct mode off"); break;
      }
    case 0x90: //printf("[FN=TURBO]");
      load_global("bedroom-lennox.turbo", &lennox_airco_turbo);
      if (lennox_airco_turbo == 0) {
        lennox_airco_turbo = 1;
        save_global("bedroom-lennox.turbo", lennox_airco_turbo);
        quicksay("bedroom air conditioner turned turbo mode on. This will help it reach the set temperature more quickly."); break;
      } else {
        lennox_airco_turbo = 0;
        save_global("bedroom-lennox.turbo", lennox_airco_turbo);
        quicksay("bedroom air conditioner turned turbo mode off"); break;
      }
    case 0xB0: //printf("[FN=CLEAN]");
      load_global("bedroom-lennox.clean", &lennox_airco_clean);
      if (lennox_airco_clean == 0) {
        lennox_airco_clean = 1;
        save_global("bedroom-lennox.clean", lennox_airco_clean);
        quicksay("bedroom air conditioner turned cleaning mode on."); break;
      } else {
        lennox_airco_clean = 0;
        save_global("bedroom-lennox.clean", lennox_airco_clean);
        quicksay("bedroom air conditioner turned cleaning mode off"); break;
      }
    default:
      //printf("[FN=UNKNOWN]");
      sprintf(message, "bedroom air conditioner toggled some unknown mode. Code is %d", code[1]);
      quicksay(message);
      break;
    }
    break;
  case 0x85:
    //fprintf(stdout, "Full state change.");
    {
    char *mode[8] = {"cool", "dry", "auto", "heat", "fan","","",""};

    load_global("bedroom-lennox.power", &lennox_airco_power);
    if ((lennox_airco_power == 0) && ((code[1]&1) == 1)) {
      //printf("[ON]");
      lennox_airco_power = 1;
      save_global("bedroom-lennox.power", lennox_airco_power);
      lennox_airco_led = 1; // LED always comes on at power-up. Possibly other toggled modes (eg swing) come up consistently too. (most likely in OFF state)
      save_global("bedroom-lennox.led", lennox_airco_led);
      quicksay("bedroom air conditioner has been turned on");
    } else if ((lennox_airco_power == 1) && ((code[1]&1) == 0)) {
      //printf("[OFF]");
      lennox_airco_power = 0;
      save_global("bedroom-lennox.power", lennox_airco_power);
      quicksay("bedroom air conditioner has been turned off"); 
    }

    load_global("bedroom-lennox.sleep", &lennox_airco_sleep);
    if ((code[1]&2) == 2) {
      //printf("[Sleep]");
      if (lennox_airco_sleep == 0) {
        lennox_airco_sleep = 1;
        save_global("bedroom-lennox.sleep", lennox_airco_sleep);
        quicksay("bedroom air conditioner has been put into sleep mode");
      }
    } else {
      if (lennox_airco_sleep == 1) {
        lennox_airco_sleep = 0;
        save_global("bedroom-lennox.sleep", lennox_airco_sleep);
        quicksay("bedroom air conditioner is no longer in sleep mode"); 
      }
    }
    if (code[4] != 0xFF) {
      int half;
      int Hr = decode_time(code[4], &half);
      //printf("[T-On=%d%s]", Hr, half ?".5":"");
      load_global("bedroom-lennox.timer-on",      &lennox_airco_timer_on);
      load_global("bedroom-lennox.timer-on-half", &lennox_airco_timer_on_half);
      if ((lennox_airco_timer_on != Hr) || (lennox_airco_timer_on_half != half)) {
        lennox_airco_timer_on = Hr;
        lennox_airco_timer_on_half = half;
        save_global("bedroom-lennox.timer-on",      lennox_airco_timer_on);
        save_global("bedroom-lennox.timer-on-half", lennox_airco_timer_on_half);
        sprintf(message, "bedroom air conditioner on Timer has been set to %d %s", Hr, (half ? "thirty":""));
        quicksay(message);
      }
    }
    if (code[3] != 0xFF) {
      int half;
      int Hr = decode_time(code[3], &half);
      //printf("[T-Off=%d%s]", Hr, half ?".5":"");
      load_global("bedroom-lennox.timer-off",      &lennox_airco_timer_off);
      load_global("bedroom-lennox.timer-off-half", &lennox_airco_timer_off_half);
      if ((lennox_airco_timer_off != Hr) || (lennox_airco_timer_off_half != half)) {
        lennox_airco_timer_off = Hr;
        lennox_airco_timer_off_half = half;
        save_global("bedroom-lennox.timer-off",      lennox_airco_timer_off);
        save_global("bedroom-lennox.timer-off-half", lennox_airco_timer_off_half);
        sprintf(message, "bedroom air conditioner Off Timer has been manually set to %d %s", Hr, (half ? "thirty":""));
        quicksay(message);
      }
    }
    if (lennox_airco_Follow) { // global state and a toggle
      //printf("[Follow]");
    }
    load_global("bedroom-lennox.mode",  &lennox_airco_mode);
    //printf("[M=%s]", mode[decode_mode(code[1], code[5])]);
    if (decode_mode(code[1], code[5]) != lennox_airco_mode) {
      lennox_airco_mode = decode_mode(code[1], code[5]);
      save_global("bedroom-lennox.mode", lennox_airco_mode);
      sprintf(message, "bedroom air conditioner mode manually changed to %s", mode[decode_mode(code[1], code[5])]);
      quicksay(message);
    }
    load_global("bedroom-lennox.fan", &lennox_airco_fan);
    if (decode_fan(code[1], code[5]) != lennox_airco_fan) {
      if ((code[1]&4) == 4) {
        printf("[Fan=Auto]");
        save_global("bedroom-lennox.fan", decode_fan(code[1], code[5]));
        quicksay("bedroom air conditioner fan manually set to automatic");
      } else {
        printf("[Fan=%d]", decode_fan(code[1], code[5]));
        save_global("bedroom-lennox.fan", decode_fan(code[1], code[5]));
        sprintf(message, "bedroom air conditioner fan speed manually set to %d", decode_fan(code[1], code[5]));
        quicksay(message);
      }
    }
    //printf("[T=%d]", F=decode_temperature(code[2], code[5])+62);
    F=decode_temperature(code[2], code[5])+62;
    load_global("bedroom-lennox.setpoint", &lennox_airco_temp);
    if (lennox_airco_temp != F) {
      lennox_airco_temp = F;
      save_global("bedroom-lennox.setpoint", lennox_airco_temp);
      sprintf(message, "bedroom air conditioner manually set to %d degrees F which is %d degrees C", F, (F-32)*5/9);
      quicksay(message);
    }
    }
    break;
  default:
    quicksay("bedroom air conditioner has received a command I don't recognise");
    //printf("Unknown decode\n");
    break;
  }  
}

// ENCODERS:

// '25' group: follow
char *construct_follow(int OnOff) {
  static int code[6]; static char hex[19];
  // Not at all sure yet what this is to be set to.  We won't be setting this.
  sprintf(hex, "25 11 f6 ff 74");
  //sprintf(hex, "25 11 f6 fc 74");
  return hex;
}

// '45' group.  They're really all toggles.
char *construct_led(int OnOff) {
  static int code[6]; static char hex[19];
  sprintf(hex, "45 10 FF FF FF");
  return hex;
}

char *construct_swing(int OnOff) {
  static int code[6]; static char hex[19];
  load_global("bedroom-lennox.swing", &lennox_airco_swing);
  sprintf(hex, "45 40 FF FF FF");
  return hex;
}

char *construct_direct(int OnOff) {
  static int code[6]; static char hex[19];
  load_global("bedroom-lennox.direct", &lennox_airco_direct);
  sprintf(hex, "45 80 FF FF FF");
  return hex;
}

char *construct_turbo(int OnOff) {
  static int code[6]; static char hex[19];
  load_global("bedroom-lennox.turbo", &lennox_airco_turbo);
  sprintf(hex, "45 90 FF FF FF");
  return hex;
}

char *construct_clean(int OnOff) {
  static int code[6]; static char hex[19];
  load_global("bedroom-lennox.clean", &lennox_airco_clean);
  sprintf(hex, "45 B0 FF FF FF");
  return hex;
}


// '85' group:
char *construct_packet(int Power, int Temp, int FanSpeed, int Mode, int Sleep, int TimerOn, int TimerOnHalf, int TimerOff, int TimerOffHalf) {
  static int code[6]; static char hex[19];
  code[0] = 0x85;
  code[1] = 0;
  if (Power) code[1] |= 1;
  if (Sleep) code[1] |= 2;
  if (FanSpeed&4) code[1] |= 4;
  if (FanSpeed&2) code[1] |= 8;
  if (FanSpeed&1) code[1] |= 16;
  if (Mode&4) code[1] |= 32;
  if (Mode&2) code[1] |= 64;
  if (Mode&1) code[1] |= 128;
  // all bits of code[1] filled.
  Temp -= 62; code[2] = 0;
  if (Temp&16) code[2] |= 8;
  if (Temp&8)  code[2] |= 16;
  if (Temp&4)  code[2] |= 32;
  if (Temp&2)  code[2] |= 64;
  if (Temp&1)  code[2] |= 128;
  code[2] |=  0 | 2 | 4; // match bits 1,2,4 to remote.
  code[3] = 0xff; // timer off  Note 0x81 bits are not determined. Timer bits are 0x7E.
  code[4] = 0xff; // timer on   Easiest to ignore timer for now.
  sprintf(hex, "%02x %02x %02x %02x %02x %02x ", code[0], code[1], code[2], code[3], code[4], crc1(code));
  return hex;
}

void remote_command(char *hex) {
  char message[1024];
  sprintf(message, "ssh pi@192.168.2.49 \"lennox-bedroom %s\" &", hex);
  fprintf(stderr, "EXECUTE: %s\n", message); fflush(stderr);
  system(message);
  fprintf(stderr, "SENT: %s\n", message); fflush(stderr);
}

void execute_lennox(char *command, char *param) {
  char message[1024];
  // convert command into 5-byte sequence and send to airco using system("ssh pi@192.168.2.49 \"lennox-bedroom xx xx xx xx xx\"");
  fprintf(stderr, "AIRCO: '%s' '%s'\n", command, param); fflush(stderr);
  if (strcmp(command, "temp")==0) {
    long temp = atol(param);
    if ((62 <= temp) && (temp <= 84)) {
      load_global("bedroom-lennox.setpoint",       &lennox_airco_temp);
      if (temp > lennox_airco_temp) {
        sprintf(message, "raising air conditioner temperature to %ld degrees F, which is %ld degrees C", temp, (temp-32)*5/9);
      } else if (temp < lennox_airco_temp) {
        sprintf(message, "lowering air conditioner temperature to %ld degrees F, which is %ld degrees C", temp, (temp-32)*5/9);
      } else {
        sprintf(message, "confirming air conditioner set to %ld degrees F, which is %ld degrees C", temp, (temp-32)*5/9);
      }
      lennox_airco_temp = temp;
      save_global("bedroom-lennox.setpoint",        lennox_airco_temp);
      quicksay(message);
      load_global("bedroom-lennox.power",          &lennox_airco_power);
      load_global("bedroom-lennox.fan",            &lennox_airco_fan);
      load_global("bedroom-lennox.mode",           &lennox_airco_mode);
      load_global("bedroom-lennox.sleep",          &lennox_airco_sleep);
      load_global("bedroom-lennox.timer-on",       &lennox_airco_timer_on);
      load_global("bedroom-lennox.timer-on-half",  &lennox_airco_timer_on_half);
      load_global("bedroom-lennox.timer-off",      &lennox_airco_timer_off);
      load_global("bedroom-lennox.timer-off-half", &lennox_airco_timer_off_half);
      remote_command(construct_packet(lennox_airco_power, lennox_airco_temp, lennox_airco_fan, lennox_airco_mode, lennox_airco_sleep, lennox_airco_timer_on, lennox_airco_timer_on_half, lennox_airco_timer_off, lennox_airco_timer_off_half));
    } else {
      quicksay("bad temperature given for bedroom air conditioner");
    }
  } else if (strcmp(command, "power")==0) {
    if (strcmp(param, "on")==0) {
      load_global("bedroom-lennox.power",          &lennox_airco_power);
      lennox_airco_power = 1;
      save_global("bedroom-lennox.power",           lennox_airco_power);
      lennox_airco_led = 1; // LED always on at power-up. Possibly other toggled modes (eg swing) come up consistently too. (most likely in OFF state)
      save_global("bedroom-lennox.led",             lennox_airco_led);
      quicksay("turning bedroom air conditioner on");
      load_global("bedroom-lennox.setpoint",       &lennox_airco_temp);
      load_global("bedroom-lennox.fan",            &lennox_airco_fan);
      load_global("bedroom-lennox.mode",           &lennox_airco_mode);
      load_global("bedroom-lennox.sleep",          &lennox_airco_sleep);
      load_global("bedroom-lennox.timer-on",       &lennox_airco_timer_on);
      load_global("bedroom-lennox.timer-on-half",  &lennox_airco_timer_on_half);
      load_global("bedroom-lennox.timer-off",      &lennox_airco_timer_off);
      load_global("bedroom-lennox.timer-off-half", &lennox_airco_timer_off_half);
      remote_command(construct_packet(lennox_airco_power, lennox_airco_temp, lennox_airco_fan, lennox_airco_mode, lennox_airco_sleep, lennox_airco_timer_on, lennox_airco_timer_on_half, lennox_airco_timer_off, lennox_airco_timer_off_half));
    } else if (strcmp(param, "off")==0) {
      load_global("bedroom-lennox.power",          &lennox_airco_power);
      lennox_airco_power = 0;
      save_global("bedroom-lennox.power",           lennox_airco_power);
      quicksay("turning bedroom air conditioner off");
      load_global("bedroom-lennox.setpoint",       &lennox_airco_temp);
      load_global("bedroom-lennox.fan",            &lennox_airco_fan);
      load_global("bedroom-lennox.mode",           &lennox_airco_mode);
      load_global("bedroom-lennox.sleep",          &lennox_airco_sleep);
      load_global("bedroom-lennox.timer-on",       &lennox_airco_timer_on);
      load_global("bedroom-lennox.timer-on-half",  &lennox_airco_timer_on_half);
      load_global("bedroom-lennox.timer-off",      &lennox_airco_timer_off);
      load_global("bedroom-lennox.timer-off-half", &lennox_airco_timer_off_half);
      remote_command(construct_packet(lennox_airco_power, lennox_airco_temp, lennox_airco_fan, lennox_airco_mode, lennox_airco_sleep, lennox_airco_timer_on, lennox_airco_timer_on_half, lennox_airco_timer_off, lennox_airco_timer_off_half));
    } else {
      quicksay("bad power parameter given for bedroom air conditioner");
    }
  } else if (strcmp(command, "led")==0) {
    if (strcmp(param, "on")==0) {
      load_global("bedroom-lennox.led", &lennox_airco_led);
      lennox_airco_led = 1;
      quicksay("turning bedroom air conditioner L E D on");
      save_global("bedroom-lennox.led",  lennox_airco_led);
      remote_command(construct_led(lennox_airco_led));
    } else if (strcmp(param, "off")==0) {
      load_global("bedroom-lennox.led", &lennox_airco_led);
      lennox_airco_led = 0;
      quicksay("turning bedroom air conditioner L E D off");
      save_global("bedroom-lennox.led",  lennox_airco_led);
      remote_command(construct_led(lennox_airco_led));
    } else {
      quicksay("bad L E D parameter given for bedroom air conditioner");
    }
  } else if (strcmp(command, "swing")==0) {
    if (strcmp(param, "on")==0) {
      load_global("bedroom-lennox.swing", &lennox_airco_swing);
      lennox_airco_swing = 1;
      quicksay("start bedroom air conditioner swing");
      save_global("bedroom-lennox.swing",  lennox_airco_swing);
      remote_command(construct_swing(lennox_airco_swing));
    } else if (strcmp(param, "off")==0) {
      load_global("bedroom-lennox.swing", &lennox_airco_swing);
      lennox_airco_swing = 0;
      quicksay("stop bedroom air conditioner swing");
      save_global("bedroom-lennox.swing",  lennox_airco_swing);
      remote_command(construct_swing(lennox_airco_swing));
    } else {
      quicksay("bad swing parameter given for bedroom air conditioner");
    }
  } else if (strcmp(command, "fan")==0) {
    if (strcmp(param, "on")==0) {
      load_global("bedroom-lennox.fan",            &lennox_airco_fan);
      lennox_airco_fan = 4; // 4 == AUTO
      quicksay("turning bedroom air conditioner fan back on");
      save_global("bedroom-lennox.fan",             lennox_airco_fan);
      load_global("bedroom-lennox.power",          &lennox_airco_power);
      load_global("bedroom-lennox.setpoint",       &lennox_airco_temp);
      load_global("bedroom-lennox.mode",           &lennox_airco_mode);
      load_global("bedroom-lennox.sleep",          &lennox_airco_sleep);
      load_global("bedroom-lennox.timer-on",       &lennox_airco_timer_on);
      load_global("bedroom-lennox.timer-on-half",  &lennox_airco_timer_on_half);
      load_global("bedroom-lennox.timer-off",      &lennox_airco_timer_off);
      load_global("bedroom-lennox.timer-off-half", &lennox_airco_timer_off_half);
      remote_command(construct_packet(lennox_airco_power, lennox_airco_temp, lennox_airco_fan, lennox_airco_mode, lennox_airco_sleep, lennox_airco_timer_on, lennox_airco_timer_on_half, lennox_airco_timer_off, lennox_airco_timer_off_half));
    } else if (strcmp(param, "off")==0) {
      load_global("bedroom-lennox.fan",            &lennox_airco_fan);
      lennox_airco_fan = 0;
      quicksay("turning bedroom air conditioner fan off");
      save_global("bedroom-lennox.fan",             lennox_airco_fan);
      load_global("bedroom-lennox.power",          &lennox_airco_power);
      load_global("bedroom-lennox.setpoint",       &lennox_airco_temp);
      load_global("bedroom-lennox.mode",           &lennox_airco_mode);
      load_global("bedroom-lennox.sleep",          &lennox_airco_sleep);
      load_global("bedroom-lennox.timer-on",       &lennox_airco_timer_on);
      load_global("bedroom-lennox.timer-on-half",  &lennox_airco_timer_on_half);
      load_global("bedroom-lennox.timer-off",      &lennox_airco_timer_off);
      load_global("bedroom-lennox.timer-off-half", &lennox_airco_timer_off_half);
      remote_command(construct_packet(lennox_airco_power, lennox_airco_temp, lennox_airco_fan, lennox_airco_mode, lennox_airco_sleep, lennox_airco_timer_on, lennox_airco_timer_on_half, lennox_airco_timer_off, lennox_airco_timer_off_half));
    } else if (strcmp(param, "high")==0) {
      load_global("bedroom-lennox.fan",            &lennox_airco_fan);
      lennox_airco_fan = 3;
      quicksay("setting bedroom air conditioner fan to high speed");
      save_global("bedroom-lennox.fan",             lennox_airco_fan);
      load_global("bedroom-lennox.power",          &lennox_airco_power);
      load_global("bedroom-lennox.setpoint",       &lennox_airco_temp);
      load_global("bedroom-lennox.mode",           &lennox_airco_mode);
      load_global("bedroom-lennox.sleep",          &lennox_airco_sleep);
      load_global("bedroom-lennox.timer-on",       &lennox_airco_timer_on);
      load_global("bedroom-lennox.timer-on-half",  &lennox_airco_timer_on_half);
      load_global("bedroom-lennox.timer-off",      &lennox_airco_timer_off);
      load_global("bedroom-lennox.timer-off-half", &lennox_airco_timer_off_half);
      remote_command(construct_packet(lennox_airco_power, lennox_airco_temp, lennox_airco_fan, lennox_airco_mode, lennox_airco_sleep, lennox_airco_timer_on, lennox_airco_timer_on_half, lennox_airco_timer_off, lennox_airco_timer_off_half));
    } else if (strcmp(param, "medium")==0) {
      load_global("bedroom-lennox.fan",            &lennox_airco_fan);
      lennox_airco_fan = 2;
      quicksay("setting bedroom air conditioner fan to medium speed");
      save_global("bedroom-lennox.fan",             lennox_airco_fan);
      load_global("bedroom-lennox.power",          &lennox_airco_power);
      load_global("bedroom-lennox.setpoint",       &lennox_airco_temp);
      load_global("bedroom-lennox.mode",           &lennox_airco_mode);
      load_global("bedroom-lennox.sleep",          &lennox_airco_sleep);
      load_global("bedroom-lennox.timer-on",       &lennox_airco_timer_on);
      load_global("bedroom-lennox.timer-on-half",  &lennox_airco_timer_on_half);
      load_global("bedroom-lennox.timer-off",      &lennox_airco_timer_off);
      load_global("bedroom-lennox.timer-off-half", &lennox_airco_timer_off_half);
      remote_command(construct_packet(lennox_airco_power, lennox_airco_temp, lennox_airco_fan, lennox_airco_mode, lennox_airco_sleep, lennox_airco_timer_on, lennox_airco_timer_on_half, lennox_airco_timer_off, lennox_airco_timer_off_half));
    } else if (strcmp(param, "low")==0) {
      load_global("bedroom-lennox.fan",            &lennox_airco_fan);
      lennox_airco_fan = 1;
      quicksay("setting bedroom air conditioner fan to low speed");
      save_global("bedroom-lennox.fan",             lennox_airco_fan);
      load_global("bedroom-lennox.power",          &lennox_airco_power);
      load_global("bedroom-lennox.setpoint",       &lennox_airco_temp);
      load_global("bedroom-lennox.mode",           &lennox_airco_mode);
      load_global("bedroom-lennox.sleep",          &lennox_airco_sleep);
      load_global("bedroom-lennox.timer-on",       &lennox_airco_timer_on);
      load_global("bedroom-lennox.timer-on-half",  &lennox_airco_timer_on_half);
      load_global("bedroom-lennox.timer-off",      &lennox_airco_timer_off);
      load_global("bedroom-lennox.timer-off-half", &lennox_airco_timer_off_half);
      remote_command(construct_packet(lennox_airco_power, lennox_airco_temp, lennox_airco_fan, lennox_airco_mode, lennox_airco_sleep, lennox_airco_timer_on, lennox_airco_timer_on_half, lennox_airco_timer_off, lennox_airco_timer_off_half));
    } else if (strcmp(param, "auto")==0) {
      load_global("bedroom-lennox.fan",            &lennox_airco_fan);
      lennox_airco_fan = 4;
      quicksay("setting bedroom air conditioner fan to automatic");
      save_global("bedroom-lennox.fan",             lennox_airco_fan);
      load_global("bedroom-lennox.power",          &lennox_airco_power);
      load_global("bedroom-lennox.setpoint",       &lennox_airco_temp);
      load_global("bedroom-lennox.mode",           &lennox_airco_mode);
      load_global("bedroom-lennox.sleep",          &lennox_airco_sleep);
      load_global("bedroom-lennox.timer-on",       &lennox_airco_timer_on);
      load_global("bedroom-lennox.timer-on-half",  &lennox_airco_timer_on_half);
      load_global("bedroom-lennox.timer-off",      &lennox_airco_timer_off);
      load_global("bedroom-lennox.timer-off-half", &lennox_airco_timer_off_half);
      remote_command(construct_packet(lennox_airco_power, lennox_airco_temp, lennox_airco_fan, lennox_airco_mode, lennox_airco_sleep, lennox_airco_timer_on, lennox_airco_timer_on_half, lennox_airco_timer_off, lennox_airco_timer_off_half));
    } else {
      quicksay("bad fan parameter given for bedroom air conditioner");
    }
  } else {
      quicksay("bad command given for bedroom air conditioner");
  }
}

// ----------------- END OF AIRCO SECTION -----------------