/**
* 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.fs20.internal;
import java.util.Dictionary;
import org.openhab.binding.fs20.FS20BindingConfig;
import org.openhab.binding.fs20.FS20BindingProvider;
import org.openhab.core.binding.AbstractBinding;
import org.openhab.core.types.Command;
import org.openhab.io.transport.cul.CULCommunicationException;
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;
/**
* This class implements the communcation between openHAB and FS20 devices. Via
* RF received updates are received directly, there is no polling.
*
* @author Till Klocke
* @since 1.4.0
*/
public class FS20Binding extends AbstractBinding<FS20BindingProvider>implements ManagedService, CULListener {
private static final Logger logger = LoggerFactory.getLogger(FS20Binding.class);
private final CULLifecycleManager culHandlerLifecycle;
public FS20Binding() {
culHandlerLifecycle = new CULLifecycleManager(CULMode.SLOW_RF,
new CULLifecycleListenerListenerRegisterer(this));
}
@Override
public void activate() {
logger.debug("Activating FS20 binding");
culHandlerLifecycle.open();
}
@Override
public void deactivate() {
logger.debug("Deactivating FS20 binding");
culHandlerLifecycle.close();
}
/**
* @{inheritDoc
*/
@Override
protected void internalReceiveCommand(String itemName, Command command) {
FS20BindingConfig bindingConfig = null;
for (FS20BindingProvider provider : super.providers) {
bindingConfig = provider.getConfigForItemName(itemName);
if (bindingConfig != null) {
break;
}
}
if (bindingConfig != null) {
logger.debug("Received command " + command.toString() + " for item " + itemName);
try {
FS20Command fs20Command = FS20CommandHelper.convertHABCommandToFS20Command(command);
culHandlerLifecycle.getCul().send("F" + bindingConfig.getAddress() + fs20Command.getHexValue());
} catch (CULCommunicationException e) {
logger.error("An exception occured while sending a command", e);
}
}
}
protected void addBindingProvider(FS20BindingProvider bindingProvider) {
super.addBindingProvider(bindingProvider);
}
protected void removeBindingProvider(FS20BindingProvider bindingProvider) {
super.removeBindingProvider(bindingProvider);
}
/**
* @{inheritDoc}
*/
@Override
public void updated(Dictionary<String, ?> config) throws ConfigurationException {
logger.debug("Received new config");
culHandlerLifecycle.config(config);
}
@Override
public void dataReceived(String data) {
// It is possible that we see here messages of other protocols
if (data.startsWith("F")) {
logger.debug("Received FS20 message: " + data);
handleReceivedMessage(data);
}
}
private void handleReceivedMessage(String message) {
String houseCode = (message.substring(1, 5));
String address = (message.substring(5, 7));
String command = message.substring(7, 9);
String fullAddress = houseCode + address;
FS20BindingConfig config = null;
for (FS20BindingProvider provider : providers) {
config = provider.getConfigForAddress(fullAddress);
if (config != null) {
break;
}
}
if (config != null) {
FS20Command fs20Command = FS20Command.getFromHexValue(command);
logger.debug("Received command " + fs20Command.toString() + " for device " + config.getAddress());
eventPublisher.postUpdate(config.getItem().getName(),
FS20CommandHelper.getStateFromFS20Command(fs20Command));
} else {
logger.debug("Received message for unknown device " + fullAddress);
}
}
@Override
public void error(Exception e) {
logger.error("Error while communicating with CUL", e);
}
}