/** * 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.fritzboxtr064.internal; import java.util.Map; import java.util.Objects; import org.apache.commons.lang.StringUtils; import org.openhab.binding.fritzboxtr064.FritzboxTr064BindingProvider; import org.openhab.binding.fritzboxtr064.internal.FritzboxTr064GenericBindingProvider.FritzboxTr064BindingConfig; import org.openhab.core.binding.AbstractActiveBinding; import org.openhab.core.items.Item; import org.openhab.core.library.items.ContactItem; import org.openhab.core.library.items.NumberItem; import org.openhab.core.library.items.StringItem; import org.openhab.core.library.items.SwitchItem; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OpenClosedType; import org.openhab.core.library.types.StringType; import org.openhab.core.types.Command; import org.openhab.core.types.State; import org.osgi.framework.BundleContext; 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 gitbock * @since 1.8.0 */ public class FritzboxTr064Binding extends AbstractActiveBinding<FritzboxTr064BindingProvider> { private static final Logger logger = LoggerFactory.getLogger(FritzboxTr064Binding.class); // URL to connect to fbox. Provided in main cfg file private String _url; // Username to use to connect to fbox private String _user; // PW private String _pw; // Call monitor class/including thread private CallMonitor _callMonitor; /** * the refresh interval which is used to poll values from the FritzboxTr064 * server (optional, defaults to 60000ms) */ private long refreshInterval = 60000; // holds Fbox TR064 connection private Tr064Comm _fboxComm = null; private PhonebookManager _pbm = null; public FritzboxTr064Binding() { } /** * Called by the SCR to activate the component with its configuration read from CAS * * @param bundleContext BundleContext of the Bundle that defines this component * @param configuration Configuration properties for this component obtained from the ConfigAdmin service */ public void activate(final BundleContext bundleContext, final Map<String, Object> configuration) { logger.debug("FritzBox TR064 Binding activated!"); // to override the default refresh interval one has to add a // parameter to openhab.cfg like <bindingName>:refresh=<intervalInMs> String refreshIntervalString = Objects.toString(configuration.get("refresh"), null); if (StringUtils.isNotBlank(refreshIntervalString)) { refreshInterval = Long.parseLong(refreshIntervalString); logger.debug("Custom refresh interval set to {}", refreshInterval); } // Check if fritzbox parameters were provided in config, otherwise does not make sense going on... String fboxurl = Objects.toString(configuration.get("url"), null); String fboxuser = Objects.toString(configuration.get("user"), null); String fboxpw = Objects.toString(configuration.get("pass"), null); if (fboxurl == null) { logger.warn("Fritzbox URL was not provided in config. Shutting down binding."); // how to shutdown?? setProperlyConfigured(false); return; } if (fboxuser == null) { logger.warn("Fritzbox User was not provided in config. Using default username."); } if (fboxpw == null) { logger.warn("Fritzbox Password was not provided in config. Shutting down binding."); // how to shutdown?? setProperlyConfigured(false); return; } this._pw = fboxpw; this._user = fboxuser; this._url = fboxurl; if (_fboxComm == null) { _fboxComm = new Tr064Comm(_url, _user, _pw); } setProperlyConfigured(true); } /** * @{inheritDoc} */ @Override protected long getRefreshInterval() { return refreshInterval; } /** * @{inheritDoc} */ @Override protected String getName() { return "FritzboxTr064 Refresh Service"; } /** * @{inheritDoc} */ @Override protected void execute() { logger.trace("FritzboxTr064 executing..."); for (FritzboxTr064BindingProvider provider : providers) { for (String itemName : provider.getItemNames()) { // check each item relevant for this binding FritzboxTr064BindingConfig conf = provider.getBindingConfigByItemName(itemName); // extract itemconfig // for current item if (conf.getConfigString().startsWith("callmonitor")) { // check if we need to start call monitor if (_callMonitor == null) { // not started yet logger.debug( "call monitor is not running. Configured items require call monitor -> Starting call monitor..."); if (_pbm == null) { logger.debug("Downloading phonebooks"); _pbm = new PhonebookManager(_fboxComm); _pbm.downloadPhonebooks(); } _callMonitor = new CallMonitor(_url, eventPublisher, providers, _pbm); _callMonitor.setupReconnectJob(); _callMonitor.startThread(); } continue; // make sure, no callmonitor items are processed by tr064 } // TR064 protocol usage String tr064result = _fboxComm.getTr064Value(conf.getConfigString()); // try to get value for this item // config string from fbox if (tr064result == null) { // if value cannot be read tr064result = "ERR"; } Class<? extends Item> itemType = conf.getItemType(); if (itemType.isAssignableFrom(StringItem.class)) { eventPublisher.postUpdate(itemName, new StringType(tr064result)); } else if (itemType.isAssignableFrom(ContactItem.class)) { State newState = tr064result.equals("1") ? OpenClosedType.OPEN : OpenClosedType.CLOSED; eventPublisher.postUpdate(itemName, newState); } else if (itemType.isAssignableFrom(SwitchItem.class)) { State newState = tr064result.equals("1") ? OnOffType.ON : OnOffType.OFF; eventPublisher.postUpdate(itemName, newState); } else if (itemType.isAssignableFrom(NumberItem.class)) { // number items e.g. TAM messages // tr064 retrieves only Strings, trying to parse value returned int val = 0; try { val = Integer.parseInt(tr064result); } catch (NumberFormatException ex) { val = -1; // indicate error as -1 } State newState = new DecimalType(val); eventPublisher.postUpdate(itemName, newState); } } } } /** * @{inheritDoc} */ @Override protected void internalReceiveCommand(String itemName, Command command) { logger.trace("internalReceiveCommand({},{}) is called!", itemName, command); if (_fboxComm == null) { _fboxComm = new Tr064Comm(_url, _user, _pw); } // Search Item Binding config for this itemName for (FritzboxTr064BindingProvider provider : providers) { FritzboxTr064BindingConfig conf = provider.getBindingConfigByItemName(itemName); if (conf != null) { _fboxComm.setTr064Value(conf.getConfigString(), command); // pass config String because config string // needed for finding item map } } } protected void addBindingProvider(FritzboxTr064BindingProvider bindingProvider) { super.addBindingProvider(bindingProvider); } protected void removeBindingProvider(FritzboxTr064BindingProvider bindingProvider) { super.removeBindingProvider(bindingProvider); } }