/** @{inheritDoc} */
  @Override
  protected void internalReceiveCommand(String itemName, Command command) {
    // the code being executed when a command was sent on the openHAB
    // event bus goes here. This method is only called if one of the
    // BindingProviders provide a binding for the given 'itemName'.

    if (command instanceof OnOffType) {
      final OnOffType switchCommand = (OnOffType) command;
      final OpenSprinklerBindingProvider bindingProvider =
          findFirstMatchingBindingProvider(itemName, command);
      final int station = bindingProvider.getStationNumber(itemName);

      if (station < 0 || station >= numberOfStations) {
        logger.warn(
            "Station "
                + station
                + " is not in the valid ["
                + 0
                + ".."
                + numberOfStations
                + "] range");
        return;
      }

      switch (switchCommand) {
        case ON:
          openSprinkler.openStation(station);
          break;
        case OFF:
          openSprinkler.closeStation(station);
          break;
      }

      return;
    }

    if (command instanceof OpenClosedType) {
      // abort processing
      return;
    }

    logger.debug("Provided command " + command + " is not of type 'OnOffType' or 'OpenClosedType'");
  }
  /** @{inheritDoc} */
  @Override
  protected void execute() {
    if (openSprinkler == null) {
      logger.debug(
          "State is not being updated with the OpenSprinkler device because access not initialized.");

      return;
    }

    logger.debug("State is being updated with the OpenSprinkler device.");

    /* Parse through all stations and update their state value */
    for (int station = 0; station < numberOfStations; station++) {
      String stationItemName = findFirstMatchingItemName(station);
      logger.debug("Checking state of item: " + stationItemName);

      if (stationItemName != null) {
        if (openSprinkler.isStationOpen(station)) {
          eventPublisher.postUpdate(stationItemName, OnOffType.ON);
        } else {
          eventPublisher.postUpdate(stationItemName, OnOffType.OFF);
        }
      }
    }

    /* Find the rain sensor item and update it with an accurate value from open sprinkler if found */
    String rainSensorItemName = findFirstMatchingItemName(RAIN_SENSOR_CONTACT_VALUE);
    logger.debug("Checking state of item: " + rainSensorItemName);

    if (rainSensorItemName != null) {
      if (openSprinkler.isRainDetected()) {
        eventPublisher.postUpdate(rainSensorItemName, OpenClosedType.OPEN);
      } else {
        eventPublisher.postUpdate(rainSensorItemName, OpenClosedType.CLOSED);
      }
    }
  }
  /** @{inheritDoc} */
  @Override
  public void updated(Dictionary<String, ?> config) throws ConfigurationException {
    if (config != null) {
      // to override the mode (gpio or http) one has to add a
      // parameter to openhab.cfg like openSprinkler:mode=[gpio|http]
      String modeString = (String) config.get("mode");
      if (StringUtils.isNotBlank(modeString)) {
        try {
          mode = OpenSprinklerMode.valueOf(modeString.toUpperCase());
        } catch (IllegalArgumentException iae) {
          throw new ConfigurationException(
              "openSprinkler:mode",
              "Unknown OpenSprinkler mode "
                  + mode
                  + "! Valid modes are 'gpio' and 'http'. Please fix your openhab.cfg.");
        }
      }

      // to specify the http url one has to add a
      // parameter to openhab.cfg like openSprinkler:httpUrl=<url>
      url = (String) config.get("httpUrl");

      // to specify the http password one has to add a
      // parameter to openhab.cfg like openSprinkler:httpPassword=<password>
      password = (String) config.get("httpPassword");

      // to override the refresh rate of the rain sensor check one has to add a
      // parameter to openhab.cfg like openSprinkler:rsRefresh
      String rsRefreshRate = (String) config.get("refreshInterval");
      if (StringUtils.isNotBlank(rsRefreshRate)) {
        refreshInterval = Long.parseLong(rsRefreshRate);
      }

      // to override the number of stations one has to add a
      // parameter to openhab.cfg like openSprinkler:numberOfStations=<count>
      String numberOfStationsString = (String) config.get("numberOfStations");
      if (StringUtils.isNotBlank(numberOfStationsString)) {
        numberOfStations = Integer.parseInt(numberOfStationsString);
        openSprinkler.setNumberOfStations(numberOfStations);
      }

      // read further config parameters here ...

      setProperlyConfigured(true);

      // then update the binding
      updateBinding();
    }
  }
  private void updateBinding() {
    if (openSprinkler != null) {
      openSprinkler.closeConnection();
    }

    if (mode == null) {
      return;
    }

    switch (mode) {
      case GPIO:
        openSprinkler = OpenSprinklerFactory.newGpioConnection();
        break;
      case HTTP:
        openSprinkler = OpenSprinklerFactory.newHttpConnection(url, password);
        break;
      default:
        throw new IllegalStateException(
            "Unknown OpenSprinkler mode: "
                + mode
                + "! Since it is checked while initialization already, this Exception should never be thrown!");
    }

    openSprinkler.setNumberOfStations(numberOfStations);

    logger.info(
        "OpenSprinkler binding running in "
            + mode
            + " mode"
            + (HTTP.equals(mode) ? " with url " + url : "")
            + ". Running with "
            + numberOfStations
            + " stations enabled and a refresh rate of "
            + refreshInterval
            + ".");
  }
 public void deactivate() {
   // deallocate Resources here that are no longer needed and
   // should be reset when activating this binding again
   openSprinkler.closeConnection();
 }