/** * Copyright (c) 2010-2016 by the respective copyright holders. * * 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.s300th.internal; import java.util.Dictionary; import org.openhab.binding.s300th.S300THBindingProvider; import org.openhab.binding.s300th.internal.S300THGenericBindingProvider.S300THBindingConfig; import org.openhab.binding.s300th.internal.S300THGenericBindingProvider.S300THBindingConfig.Datapoint; import org.openhab.core.binding.AbstractBinding; import org.openhab.core.items.Item; import org.openhab.core.library.types.DecimalType; import org.openhab.io.transport.cul.CULLifecycleListenerListenerRegisterer; import org.openhab.io.transport.cul.CULLifecycleManager; import org.openhab.io.transport.cul.CULListener; import org.openhab.io.transport.cul.CULMode; import org.osgi.service.cm.ConfigurationException; import org.osgi.service.cm.ManagedService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Implement this class if you are going create an actively polling service like * querying a Website/Device. * * @author Till Klocke * @since 1.4.0 */ public class S300THBinding extends AbstractBinding<S300THBindingProvider>implements ManagedService, CULListener { private static final Logger logger = LoggerFactory.getLogger(S300THBinding.class); private final static String KS_300_ADDRESS = "ks300"; private final CULLifecycleManager culHandlerLifecycle; public S300THBinding() { culHandlerLifecycle = new CULLifecycleManager(CULMode.SLOW_RF, new CULLifecycleListenerListenerRegisterer(this)); } @Override public void activate() { culHandlerLifecycle.open(); } @Override public void deactivate() { culHandlerLifecycle.close(); } protected void addBindingProvider(S300THBindingProvider bindingProvider) { super.addBindingProvider(bindingProvider); } protected void removeBindingProvider(S300THBindingProvider bindingProvider) { super.removeBindingProvider(bindingProvider); } /** * {@inheritDoc} */ @Override public void updated(Dictionary<String, ?> config) throws ConfigurationException { culHandlerLifecycle.config(config); } @Override public void dataReceived(String data) { if (data.startsWith("K")) { int firstByte = Integer.parseInt(data.substring(1, 2), 16); int typByte = Integer.parseInt(data.substring(2, 3), 16) & 7; int sfirstByte = firstByte & 7; if (sfirstByte == 7) { logger.debug("Received WS7000 message, but parsing for WS7000 is not implemented"); // TODO parse different sensors from WS7000 (?) } else { if (data.length() > 8 && data.length() < 13) { // S300TH default size = 9 characters parseS300THData(data); } else if (data.length() > 14 && data.length() < 20) { // KS300 default size = 15 characters. // sometime we got values with more characters. parseKS300Data(data); } else { logger.warn("Received unparseable message: " + data); } } } } /** * Parse KS 300 data * * @param data */ private void parseKS300Data(String data) { // TODO parse address and other bytes int rainValue = ParseUtils.parseKS300RainCounter(data); double windValue = ParseUtils.parseKS300Wind(data); double humidity = ParseUtils.parseKS300Humidity(data); double temperature = ParseUtils.parseTemperature(data); boolean isRaining = ParseUtils.isKS300Raining(data); logger.debug("Received data '" + data + "' from device with address ks300 : temperature: " + temperature + " humidity: " + humidity + " wind: " + windValue + " rain: " + rainValue + " isRain: " + isRaining); for (Datapoint datapoint : Datapoint.values()) { S300THBindingConfig config = findConfig(KS_300_ADDRESS, datapoint); if (config == null) { continue; } double value = 0.0; switch (datapoint) { case TEMPERATURE: value = temperature; break; case HUMIDITY: value = humidity; break; case WIND: value = windValue; break; case RAIN: value = rainValue; break; case IS_RAINING: value = isRaining ? 1 : 0; break; } updateItem(config.item, value); } } /** * Parse S300TH data * * @param data */ private void parseS300THData(String data) { String address = ParseUtils.parseS300THAddress(data); double temperature = ParseUtils.parseTemperature(data); double humidity = ParseUtils.parseS300THHumidity(data); logger.debug("Received data '" + data + "' from device with address " + address + " : temperature: " + temperature + " humidity: " + humidity); S300THBindingConfig temperatureConfig = findConfig(address, Datapoint.TEMPERATURE); if (temperatureConfig != null) { updateItem(temperatureConfig.item, temperature); } S300THBindingConfig humidityConfig = findConfig(address, Datapoint.HUMIDITY); if (humidityConfig != null) { updateItem(humidityConfig.item, humidity); } } private void updateItem(Item item, double value) { DecimalType type = new DecimalType(value); eventPublisher.postUpdate(item.getName(), type); } private S300THBindingConfig findConfig(String address, Datapoint datapoint) { for (S300THBindingProvider provider : this.providers) { S300THBindingConfig config = provider.getBindingConfigForAddressAndDatapoint(address, datapoint); if (config != null) { return config; } } return null; } @Override public void error(Exception e) { logger.error("Received error from CUL instead of data", e); } }