/**
   * Receives a command from openHAB and translates it to an operation on the Z-Wave network.
   *
   * @param provider the {@link ZWaveBindingProvider} that provides the item
   * @param itemName the name of the item that will receive the event.
   * @param command the received {@link Command}
   */
  @SuppressWarnings("unchecked")
  public void receiveCommand(ZWaveBindingProvider provider, String itemName, Command command) {
    ZWaveBindingConfig bindingConfiguration = provider.getZwaveBindingConfig(itemName);
    ZWaveNode node = this.controller.getNode(bindingConfiguration.getNodeId());
    ZWaveCommandClass commandClass;
    String commandClassName = bindingConfiguration.getArguments().get("command");

    // ignore nodes that are not initialized or dead.
    if (node.getNodeStage() != NodeStage.DONE) return;

    if (commandClassName != null) {
      commandClass =
          node.resolveCommandClass(
              CommandClass.getCommandClass(commandClassName), bindingConfiguration.getEndpoint());

      if (commandClass == null) {
        logger.warn(
            "No command class found for item = {}, command class name = {}, ignoring command.",
            itemName,
            commandClassName);
        return;
      }
    } else {
      commandClass =
          resolveConverter(provider.getItem(itemName), node, bindingConfiguration.getEndpoint());
    }

    if (commandClass == null) {
      logger.warn("No converter found for item = {}, ignoring command.", itemName);
      return;
    }

    ZWaveCommandClassConverter<ZWaveCommandClass> converter =
        (ZWaveCommandClassConverter<ZWaveCommandClass>)
            getConverter(commandClass.getCommandClass());

    if (converter == null) {
      logger.warn("No converter found for item = {}, ignoring command.", itemName);
      return;
    }

    converter.receiveCommand(
        provider.getItem(itemName),
        command,
        node,
        commandClass,
        bindingConfiguration.getEndpoint(),
        bindingConfiguration.getArguments());
  }
예제 #2
0
  /**
   * Adds a command class to the list of supported command classes by this endpoint. Does nothing if
   * command class is already added.
   *
   * @param commandClass the command class instance to add.
   */
  public void addCommandClass(ZWaveCommandClass commandClass) {
    CommandClass key = commandClass.getCommandClass();

    if (!supportedCommandClasses.containsKey(key)) {
      supportedCommandClasses.put(key, commandClass);
    }
  }
  /**
   * Returns the command class that provides the best suitable converter to convert between the
   * Z-Wave API and the binding.
   *
   * @param item the {@link item} to resolve a converter for.
   * @param node the {@link ZWaveNode} node to resolve a Command class on.
   * @param the enpoint ID to use to resolve a converter.
   * @return the {@link ZWaveCommandClass} that can be used to get a converter suitable to do the
   *     conversion.
   */
  private ZWaveCommandClass resolveConverter(Item item, ZWaveNode node, int endpointId) {
    if (item == null) return null;

    ZWaveMultiInstanceCommandClass multiInstanceCommandClass = null;
    ZWaveCommandClass result = null;

    if (endpointId != 1)
      multiInstanceCommandClass =
          (ZWaveMultiInstanceCommandClass) node.getCommandClass(CommandClass.MULTI_INSTANCE);

    if (!preferredCommandClasses.containsKey(item.getClass())) {
      logger.warn(
          "No preferred command classes found for item class = {}", item.getClass().toString());
      return null;
    }

    for (CommandClass commandClass : preferredCommandClasses.get(item.getClass())) {
      if (multiInstanceCommandClass != null && multiInstanceCommandClass.getVersion() == 2) {
        ZWaveEndpoint endpoint = multiInstanceCommandClass.getEndpoint(endpointId);

        if (endpoint != null) {
          result = endpoint.getCommandClass(commandClass);
        }
      }

      if (result == null) result = node.getCommandClass(commandClass);

      if (result == null) continue;

      if (multiInstanceCommandClass != null
          && multiInstanceCommandClass.getVersion() == 1
          && result.getInstances() < endpointId) continue;

      if (converters.containsKey(commandClass)) return result;
    }

    logger.warn(
        "No matching command classes found for item class = {}, node id = {}, endpoint id = {}",
        item.getClass().toString(),
        node.getNodeId(),
        endpointId);
    return null;
  }
  /**
   * Execute refresh method. This method is called every time a binding item is refreshed and the
   * corresponding node should be sent a message.
   *
   * @param provider the {@link ZWaveBindingProvider} that provides the item
   * @param itemName the name of the item to poll.
   * @param forceRefresh indicates that a polling refresh should be forced.
   */
  @SuppressWarnings("unchecked")
  public void executeRefresh(ZWaveBindingProvider provider, String itemName, boolean forceRefresh) {
    ZWaveBindingConfig bindingConfiguration = provider.getZwaveBindingConfig(itemName);
    ZWaveCommandClass commandClass;
    String commandClassName = bindingConfiguration.getArguments().get("command");

    // this binding is configured not to poll.
    if (!forceRefresh
        && bindingConfiguration.getRefreshInterval() != null
        && 0 == bindingConfiguration.getRefreshInterval()) return;

    ZWaveNode node = this.controller.getNode(bindingConfiguration.getNodeId());

    // ignore nodes that are not initialized or dead.
    if (node == null) return;

    if (commandClassName != null) {

      // this is a report item, handle it with the report info converter.
      if (commandClassName.equalsIgnoreCase("info")) {
        infoConverter.executeRefresh(
            provider.getItem(itemName),
            node,
            bindingConfiguration.getEndpoint(),
            bindingConfiguration.getArguments());
        return;
      }

      // ignore nodes that are not initialized or dead.
      if (node.getNodeStage() != NodeStage.DONE) return;

      commandClass =
          node.resolveCommandClass(
              CommandClass.getCommandClass(commandClassName), bindingConfiguration.getEndpoint());

      if (commandClass == null) {
        logger.warn(
            "No command class found for item = {}, command class name = {}, ignoring execute refresh.",
            itemName,
            commandClassName);
        return;
      }
    } else {
      commandClass =
          resolveConverter(provider.getItem(itemName), node, bindingConfiguration.getEndpoint());
    }

    if (commandClass == null) {
      logger.warn("No converter found for item = {}, ignoring execute refresh.", itemName);
      return;
    }

    ZWaveCommandClassConverter<ZWaveCommandClass> converter =
        (ZWaveCommandClassConverter<ZWaveCommandClass>)
            getConverter(commandClass.getCommandClass());

    if (converter == null) {
      logger.warn("No converter found for item = {}, ignoring execute refresh.", itemName);
      return;
    }

    if (bindingConfiguration.getRefreshInterval() == null) {
      bindingConfiguration.setRefreshInterval(converter.getRefreshInterval());

      // this binding is configured not to poll.
      if (!forceRefresh && 0 == bindingConfiguration.getRefreshInterval()) return;
    }

    // not enough time has passed to refresh the item.
    if (!forceRefresh
        && bindingConfiguration.getLastRefreshed() != null
        && (bindingConfiguration.getLastRefreshed().getTime()
                + (bindingConfiguration.getRefreshInterval() * 1000)
            > Calendar.getInstance().getTimeInMillis())) return;

    bindingConfiguration.setLastRefreshed(Calendar.getInstance().getTime());
    converter.executeRefresh(
        node,
        commandClass,
        bindingConfiguration.getEndpoint(),
        bindingConfiguration.getArguments());
  }