Package org.openhab.binding.nibeheatpump.internal

Source Code of org.openhab.binding.nibeheatpump.internal.NibeHeatPumpBinding

/**
* 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.nibeheatpump.internal;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;

import javax.xml.bind.DatatypeConverter;

import org.apache.commons.lang.StringUtils;
import org.openhab.binding.nibeheatpump.NibeHeatPumpBindingProvider;
import org.openhab.binding.nibeheatpump.protocol.NibeHeatPumpConnector;
import org.openhab.binding.nibeheatpump.protocol.NibeHeatPumpDataParser;
import org.openhab.binding.nibeheatpump.protocol.NibeHeatPumpSimulator;
import org.openhab.binding.nibeheatpump.protocol.NibeHeatPumpDataParser.VariableInformation;
import org.openhab.binding.nibeheatpump.protocol.NibeHeatPumpSerialConnector;
import org.openhab.binding.nibeheatpump.protocol.NibeHeatPumpUDPConnector;
import org.openhab.core.binding.AbstractBinding;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.types.State;
import org.openhab.core.types.UnDefType;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
*
* Binding to receive data from Nibe heat pumps.
*
* @author Pauli Anttila
* @since 1.3.0
*/
public class NibeHeatPumpBinding extends
    AbstractBinding<NibeHeatPumpBindingProvider> implements ManagedService {

  private static final Logger logger = LoggerFactory.getLogger(NibeHeatPumpBinding.class);

  /* configuration variables for communication */
  private int udpPort = 9999;
  private String serialPort = null;
  private boolean simulateHeatPump = false;

  /** Thread to handle messages from heat pump */
  private NibeHeatPumpMessageListener messageListener = null;


  public void activate() {
    logger.debug("Activate");
  }

  public void deactivate() {
    logger.debug("Deactivate");
    messageListener.setInterrupted(true);
    messageListener.interrupt();
  }
 
 
  /**
   * @{inheritDoc
   */
  @Override
  public void updated(Dictionary<String, ?> config) throws ConfigurationException {

    logger.debug("Configuration updated, config {}", config != null ? true : false);

    if (config != null) {
      String PortString = (String) config.get("udpPort");
      if (StringUtils.isNotBlank(PortString)) {
        udpPort = Integer.parseInt(PortString);
      }

      serialPort = (String) config.get("serialPort");

      String testPortString = (String) config.get("simulate");
      if (StringUtils.isNotBlank(testPortString)) {
        simulateHeatPump = Boolean.parseBoolean(testPortString);
      }
     
      if (messageListener != null) {

        logger.debug("Close previous message listener");

        messageListener.setInterrupted(true);
        try {
          messageListener.join();
        } catch (InterruptedException e) {
          logger.info("Previous message listener closing interrupted", e);
        }
      }
     
      messageListener = new NibeHeatPumpMessageListener();
      messageListener.start();
    }
  }

  private State convertNibeValueToState(NibeHeatPumpDataParser.NibeDataType dataType, double value) {
    org.openhab.core.types.State state = UnDefType.UNDEF;

    switch (dataType) {
      case U8:
      case U16:
      case U32:
        state = new DecimalType((long) value);
        break;
      case S8:
      case S16:
      case S32:
        BigDecimal bd = new BigDecimal(value).setScale(2, RoundingMode.HALF_EVEN);
        state = new DecimalType(bd);
        break;
    }

    return state;
  }

  /**
   * The NibeHeatPumpMessageListener runs as a separate thread. The Thread is listening
   * message from heat pump and send updates to openHAB bus.
   */
  private class NibeHeatPumpMessageListener extends Thread {

    private boolean interrupted = false;
   
    public void setInterrupted(boolean interrupted) {
      this.interrupted = interrupted;
    }

    @Override
    public void run() {
      logger.debug("Nibe heatpump message listener started");

      NibeHeatPumpConnector connector;
     
      if (simulateHeatPump == true) {
        connector = new NibeHeatPumpSimulator();
      } else if (serialPort != null) {
        connector = new NibeHeatPumpSerialConnector(serialPort);
      } else {
        connector = new NibeHeatPumpUDPConnector(udpPort);
      }
     
      try {
        connector.connect();
      } catch (NibeHeatPumpException e) {
        logger.error("Error occured when connecting to heat pump", e);
       
        logger.warn("Closing Nibe heatpump message listener");

        // exit
        interrupted = true;
      }

      // as long as no interrupt is requested, continue running
      while (!interrupted) {
        try {
          // Wait a packet (blocking)
          byte[] data = connector.receiveDatagram();

          logger.debug("Received data (len={}): {}", data.length, DatatypeConverter.printHexBinary(data));

          Hashtable<Integer, Short> regValues = NibeHeatPumpDataParser.ParseData(data);

          if (regValues != null) {

            Enumeration<Integer> keys = regValues.keys();

            while (keys.hasMoreElements()) {

              int key = keys.nextElement();
              double value = regValues.get(key);

              VariableInformation variableInfo = NibeHeatPumpDataParser.VARIABLE_INFO_F1145_F1245
                  .get(key);

              if (variableInfo == null) {
                logger.debug("Unknown variable {}", key);
              } else {
                value = value / variableInfo.factor;
                org.openhab.core.types.State state = convertNibeValueToState(
                    variableInfo.dataType, value);

                logger.debug("{}={}", key + ":"
                    + variableInfo.variable, value);

                for (NibeHeatPumpBindingProvider provider : providers) {
                  for (String itemName : provider
                      .getItemNames()) {
                    int itemId = provider
                        .getItemId(itemName);
                    if (key == itemId) {
                      eventPublisher.postUpdate(itemName,
                          state);
                    }
                  }
                }
              }
            }

          }
        } catch (NibeHeatPumpException e) {
          logger.error("Error occured when received data from heat pump", e);
        }
      }
     
      try {
        connector.disconnect();
      } catch (NibeHeatPumpException e) {
        logger.error("Error occured when disconnecting form heat pump", e);
      }
    }

  }

}
TOP

Related Classes of org.openhab.binding.nibeheatpump.internal.NibeHeatPumpBinding

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.