/**
   * Get the state from the house
   *
   * @return the new state of things
   */
  public synchronized Hashtable<String, Object> getState() {

    System.out.println("Requesting state");

    synchronized (connection) {
      String update = connection.sendMessageToHouse(IoTValues.GET_STATE + IoTValues.MSG_END);
      if (update == null) {
        return null;
      }

      return handleStateUpdate(update);
    }
  }
  /**
   * Send a state change request to the house
   *
   * @param state the new state
   * @return true if the state was accepted; false otherwise
   */
  public synchronized Boolean setState(Hashtable<String, Object> state) {

    StringBuffer newState = new StringBuffer();
    Set<String> keys = state.keySet();
    int count = 0;
    for (String key : keys) {

      if (key.equals(IoTValues.DOOR_STATE)) {

        Boolean newDoorState = (Boolean) state.get(key);
        newState.append(IoTValues.DOOR_STATE);
        newState.append(IoTValues.PARAM_EQ);
        if (newDoorState) {
          newState.append(IoTValues.DOOR_OPEN);
        } else {
          newState.append(IoTValues.DOOR_CLOSE);
        }
        count++;
        if (count < keys.size()) {
          newState.append(IoTValues.PARAM_DELIM);
        }
      } else if (key.equals(IoTValues.LIGHT_STATE)) {
        Boolean newLightState = (Boolean) state.get(key);
        newState.append(IoTValues.LIGHT_STATE);
        newState.append(IoTValues.PARAM_EQ);
        if (newLightState) {
          newState.append(IoTValues.LIGHT_ON);
        } else {
          newState.append(IoTValues.LIGHT_OFF);
        }
        count++;
        if (count < keys.size()) {
          newState.append(IoTValues.PARAM_DELIM);
        }
      } else if (key.equals(IoTValues.PROXIMITY_STATE)) { // bug: light -> proximity
        Boolean newHumidifierState = (Boolean) state.get(key);
        newState.append(IoTValues.PROXIMITY_STATE);
        newState.append(IoTValues.PARAM_EQ);
        if (newHumidifierState) {
          newState.append(IoTValues.PROXIMITY_ON);
        } else {
          newState.append(IoTValues.PROXIMITY_OFF);
        }
        count++;
        if (count < keys.size()) {
          newState.append(IoTValues.PARAM_DELIM);
        }
      } else if (key.equals(IoTValues.ALARM_STATE)) {
        Boolean newAlarmState = (Boolean) state.get(key);
        newState.append(IoTValues.ALARM_STATE);
        newState.append(IoTValues.PARAM_EQ);
        if (newAlarmState) {
          newState.append(IoTValues.ALARM_ENABLED);
        } else {
          newState.append(IoTValues.ALARM_DISABLED);
        }
        count++;
        if (count < keys.size()) {
          newState.append(IoTValues.PARAM_DELIM);
        }
      } else if (key.equals(IoTValues.HUMIDIFIER_STATE)) { // bug: alarm -> humidifier
        Boolean newHumidifierState = (Boolean) state.get(key);
        newState.append(IoTValues.HUMIDIFIER_STATE);
        newState.append(IoTValues.PARAM_EQ);
        if (newHumidifierState) {
          newState.append(IoTValues.HUMIDIFIER_ON);
        } else {
          newState.append(IoTValues.HUMIDIFIER_OFF);
        }
        count++;
        if (count < keys.size()) {
          newState.append(IoTValues.PARAM_DELIM);
        }
      } else if (key.equals(IoTValues.CHILLER_STATE)) {
        Boolean newChillerState = (Boolean) state.get(key);
        newState.append(IoTValues.CHILLER_STATE);
        newState.append(IoTValues.PARAM_EQ);
        if (newChillerState) {
          newState.append(IoTValues.CHILLER_ON);
        } else {
          newState.append(IoTValues.CHILLER_OFF);
        }
        count++;
        if (count < keys.size()) {
          newState.append(IoTValues.PARAM_DELIM);
        }
      } else if (key.equals(IoTValues.HEATER_STATE)) {
        Boolean newHeaterState = (Boolean) state.get(key);
        newState.append(IoTValues.HEATER_STATE);
        newState.append(IoTValues.PARAM_EQ);
        if (newHeaterState) {
          newState.append(IoTValues.HEATER_ON);
        } else {
          newState.append(IoTValues.HEATER_OFF);
        }
        count++;
        if (count < keys.size()) {
          newState.append(IoTValues.PARAM_DELIM);
        }
      }
    }

    // newState.append(IoTValues.MSG_END); // append protocol request terminator
    StringBuffer msg =
        new StringBuffer(
            IoTValues.SET_STATE + IoTValues.MSG_DELIM + newState.toString() + IoTValues.MSG_END);
    System.out.println("New state: " + msg.toString());

    String response = null;
    synchronized (connection) {
      response = connection.sendMessageToHouse(msg.toString());
    }
    if (response == null) {
      return false;
    }
    return response.equals(IoTValues.OK);
  }
 /**
  * Get the connected state
  *
  * @return true if connected, false otherwise
  */
 public Boolean isConnected() {
   if (connection != null) {
     return connection.isConnected();
   }
   return false;
 }
 /** Disconnect from the house */
 public void disconnectFromHouse() {
   connection.disconnect();
 }