/**
* 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.rwesmarthome.internal;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.openhab.binding.rwesmarthome.RWESmarthomeBindingProvider;
import org.openhab.binding.rwesmarthome.internal.communicator.RWESmarthomeCommunicator;
import org.openhab.core.binding.AbstractActiveBinding;
import org.openhab.core.events.EventPublisher;
import org.openhab.core.types.Command;
import org.osgi.framework.BundleContext;
import org.osgi.service.cm.ConfigurationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* RWE Smarthome binding implementation.
*
* @author ollie-dev
* @since 1.8.0
*/
public class RWESmarthomeBinding extends AbstractActiveBinding<RWESmarthomeBindingProvider> {
private static final Logger logger = LoggerFactory.getLogger(RWESmarthomeBinding.class);
private RWESmarthomeCommunicator communicator = new RWESmarthomeCommunicator();
private RWESmarthomeContext context = RWESmarthomeContext.getInstance();
/**
* the refresh interval which is used to poll values from the RWESmarthome
* server (optional, defaults to 2000ms)
*/
private long refreshInterval = 2000;
/**
* stores the time when context.setBindingChanged to true
*/
private long lastBindingChangedTime = 0;
/**
* {@inheritDoc}
*/
public void activate(final BundleContext bundleContext, final Map<String, Object> configuration)
throws ConfigurationException {
logger.debug("activate is called.");
context.setProviders(providers);
String refreshIntervalString = (String) configuration.get("poll.interval");
if (StringUtils.isNotBlank(refreshIntervalString)) {
refreshInterval = Long.parseLong(refreshIntervalString);
}
// read further config parameters here ...
context.getConfig().parse(configuration);
logger.debug(context.getConfig().toString());
communicator.start();
setProperlyConfigured(true);
}
protected void addBindingProvider(RWESmarthomeBindingProvider bindingProvider) {
super.addBindingProvider(bindingProvider);
}
protected void removeBindingProvider(RWESmarthomeBindingProvider bindingProvider) {
super.removeBindingProvider(bindingProvider);
}
/**
* {@inheritDoc}
*/
public void modified(final Map<String, Object> configuration) throws ConfigurationException {
logger.debug("modified called");
if (configuration != null) {
setProperlyConfigured(false);
communicator.stop();
context.getConfig().parse(configuration);
logger.info(context.getConfig().toString());
if (context.getConfig().isValid()) {
communicator.start();
setProperlyConfigured(true);
}
} else {
logger.info(
"RWE Smarthome binding configuration is not present. Please check your configuration file or if not needed remove the RWE Smarthome binding addon.");
}
}
/**
* {@inheritDoc}
*/
public void deactivate(final int reason) {
logger.debug("Deactivate is called. Reason: {}", reason);
communicator.stop();
// TODO: further deallocation of unneeded resources
}
/**
* Saves the eventPublisher in the RweSmarthome context.
*/
@Override
public void setEventPublisher(EventPublisher eventPublisher) {
super.setEventPublisher(eventPublisher);
context.setEventPublisher(eventPublisher);
}
/**
* @{inheritDoc}
*/
@Override
protected long getRefreshInterval() {
return refreshInterval;
}
/**
* @{inheritDoc}
*/
@Override
protected String getName() {
return "RWESmarthome Refresh Service";
}
/**
* @{inheritDoc}
*/
@Override
protected void execute() {
// the frequently executed code (polling) goes here ...
logger.trace("execute() method is called!");
// restart communicator (=rebuild RWE binding data), if there was no communication for a time (default: 5 min)
long timeSinceLastEvent = (System.currentTimeMillis() - communicator.getLastEventTime()) / 1000;
if (timeSinceLastEvent > context.getConfig().getAliveInterval()) {
logger.info("No event since {} seconds, refreshing RweSmarthome server connections", timeSinceLastEvent);
communicator.stop();
communicator.start();
}
// if bindingChanged is set, save the current time
if (context.getBindingChanged()) {
lastBindingChangedTime = System.currentTimeMillis();
context.setBindingChanged(false);
}
if (lastBindingChangedTime > 0) {
long timeSinceBindingChanged = (System.currentTimeMillis() - lastBindingChangedTime) / 1000;
if (timeSinceBindingChanged > context.getConfig().getBindingChangedInterval()) {
logger.info("Binding changed - reload RWE Smarthome data");
communicator.loadDeviceStates();
lastBindingChangedTime = 0;
}
}
communicator.poll();
if (logger.isTraceEnabled()) {
for (String key : context.getIgnoreEventList().keySet()) {
logger.trace("Ignorelist: {} {} (age: {} ms)", key, context.getIgnoreEventList().get(key),
System.currentTimeMillis() - context.getIgnoreEventList().get(key));
}
}
}
/**
* @{inheritDoc}
*/
@Override
protected void internalReceiveCommand(String itemName, Command command) {
if (communicator.isRunning()) {
logger.debug("internalReceiveCommand({},{}) is called!", itemName, command);
communicator.sendCommand(itemName, command);
context.getIgnoreEventList().put(itemName + command.toString(), System.currentTimeMillis());
logger.debug("Added event (item='{}', command='{}') to the ignore event list", itemName,
command.toString());
} else {
logger.info("Command '{}' for item '{}' not executed: communicator not running.", command, itemName);
}
}
}