Package org.openhab.binding.astro.internal.bus

Source Code of org.openhab.binding.astro.internal.bus.PlanetPublisher

/**
* Copyright (c) 2010-2014, openHAB.org and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.openhab.binding.astro.internal.bus;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import org.openhab.binding.astro.AstroBindingProvider;
import org.openhab.binding.astro.internal.common.AstroContext;
import org.openhab.binding.astro.internal.config.AstroBindingConfig;
import org.openhab.binding.astro.internal.model.Planet;
import org.openhab.binding.astro.internal.model.PlanetName;
import org.openhab.binding.astro.internal.util.ItemIterator;
import org.openhab.binding.astro.internal.util.ItemIterator.ItemIteratorCallback;
import org.openhab.binding.astro.internal.util.PropertyUtils;
import org.openhab.core.items.Item;
import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.types.UnDefType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Publishes object properties to items.
*
* @author Gerhard Riegler
* @since 1.6.0
*/
public class PlanetPublisher {
  private static final Logger logger = LoggerFactory.getLogger(PlanetPublisher.class);
  private AstroContext context = AstroContext.getInstance();
  private Map<String, Object> itemCache = new HashMap<String, Object>();

  private static PlanetPublisher instance = null;

  private PlanetPublisher() {
  }

  /**
   * Returns the singleton instance of PlanetPublisher.
   */
  public static PlanetPublisher getInstance() {
    if (instance == null) {
      instance = new PlanetPublisher();
    }
    return instance;
  }

  /**
   * Clears the item cache.
   */
  public void clear() {
    itemCache.clear();
  }

  /**
   * Republish the state of the item.
   */
  public void republishItem(String itemName) {
    AstroBindingConfig bindingConfig = null;
    for (AstroBindingProvider provider : context.getProviders()) {
      if (bindingConfig == null) {
        bindingConfig = provider.getBindingFor(itemName);
      }
    }
    if (bindingConfig == null) {
      logger.warn("Astro binding for item {} not found", itemName);
    } else {
      itemCache.remove(itemName);
      publish(bindingConfig.getPlanetName());
    }
  }

  /**
   * Iterates through all items and publishes the states.
   */
  public void publish(final PlanetName planetName) {
    final Planet planet = context.getPlanet(planetName);
    new ItemIterator().iterate(new ItemIteratorCallback() {

      @Override
      public void next(AstroBindingConfig bindingConfig, Item item) {
        if (planetName == bindingConfig.getPlanetName()) {
          try {
            Object value = PropertyUtils.getPropertyValue(planet, bindingConfig.getPlanetProperty());
            if (!equalsCachedValue(value, item)) {
              publishValue(item, value, bindingConfig);
              itemCache.put(item.getName(), value);
            }
          } catch (Exception ex) {
            logger.warn(ex.getMessage(), ex);
          }
        }
      }
    });
  }

  /**
   * Returns true, if the cached value is equal to the new value.
   */
  private boolean equalsCachedValue(Object value, Item item) {
    int cachedValueHashCode = ObjectUtils.hashCode(itemCache.get(item.getName()));
    int valueHashCode = ObjectUtils.hashCode(value);
    return cachedValueHashCode == valueHashCode;
  }

  /**
   * Publishes the item with the value, if the item is a OnOffType and the
   * value is a calendar, a job is scheduled.
   */
  private void publishValue(Item item, Object value, AstroBindingConfig bindingConfig) {
    if (value == null) {
      context.getEventPublisher().postUpdate(item.getName(), UnDefType.UNDEF);
    } else if (value instanceof Calendar) {
      Calendar calendar = (Calendar) value;
      if (bindingConfig.getOffset() != 0) {
        calendar = (Calendar) calendar.clone();
        calendar.add(Calendar.MINUTE, bindingConfig.getOffset());
      }

      if (item.getAcceptedDataTypes().contains(DateTimeType.class)) {
        context.getEventPublisher().postUpdate(item.getName(), new DateTimeType(calendar));
      } else if (item.getAcceptedCommandTypes().contains(OnOffType.class)) {
        context.getJobScheduler().scheduleItem(calendar, item.getName());
      } else {
        logger.warn("Unsupported type for item {}, only DateTimeType and OnOffType supported!", item.getName());
      }
    } else if (value instanceof Number) {
      if (item.getAcceptedDataTypes().contains(DecimalType.class)) {
        BigDecimal decimalValue = new BigDecimal(value.toString()).setScale(2, RoundingMode.HALF_UP);
        context.getEventPublisher().postUpdate(item.getName(), new DecimalType(decimalValue));
      } else if (value instanceof Long && item.getAcceptedDataTypes().contains(StringType.class)
          && "duration".equals(bindingConfig.getProperty())) {
        // special case, transforming duration to minute:second string
        context.getEventPublisher().postUpdate(item.getName(), new StringType(durationToString((Long) value)));
      } else {
        logger.warn("Unsupported type for item {}, only DecimalType supported!", item.getName());
      }
    } else if (value instanceof String || value instanceof Enum) {
      if (item.getAcceptedDataTypes().contains(StringType.class)) {
        if (value instanceof Enum) {
          String enumValue = WordUtils.capitalizeFully(StringUtils.replace(value.toString(), "_", " "));
          context.getEventPublisher().postUpdate(item.getName(), new StringType(enumValue));
        } else {
          context.getEventPublisher().postUpdate(item.getName(), new StringType(value.toString()));
        }
      } else {
        logger.warn("Unsupported type for item {}, only String supported!", item.getName());
      }

    } else {
      logger.warn("Unsupported value type {}", value.getClass().getSimpleName());
    }
  }

  /**
   * Returns the minute:second string for the minutes number.
   */
  private String durationToString(long minutes) {
    long hours = minutes / 60;
    minutes -= hours * 60;

    StringWriter sw = new StringWriter();
    PrintWriter writer = new PrintWriter(sw);

    writer.printf("%02d:%02d", hours, minutes);

    writer.flush();
    return sw.getBuffer().toString();
  }

}
TOP

Related Classes of org.openhab.binding.astro.internal.bus.PlanetPublisher

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.