/** * 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.enigma2.internal; import java.util.Collection; import java.util.Dictionary; import java.util.Enumeration; import java.util.HashMap; import org.apache.commons.lang.StringUtils; import org.openhab.binding.enigma2.Enigma2BindingProvider; import org.openhab.core.binding.AbstractActiveBinding; import org.openhab.core.items.GenericItem; import org.openhab.core.items.Item; import org.openhab.core.library.items.DimmerItem; import org.openhab.core.library.items.NumberItem; 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.PercentType; import org.openhab.core.library.types.StringType; import org.openhab.core.types.Command; import org.openhab.core.types.State; 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 Sebastian Kutschbach * @since 1.6.0 */ public class Enigma2Binding extends AbstractActiveBinding<Enigma2BindingProvider>implements ManagedService { private static final Logger logger = LoggerFactory.getLogger(Enigma2Binding.class); private HashMap<String, Enigma2Node> enigmaNodes = new HashMap<String, Enigma2Node>(); /** * the refresh interval which is used to poll values from the Enigma2 server * (optional, defaults to 60000ms) */ private long refreshInterval = 60000; public Enigma2Binding() { } @Override public void activate() { } @Override public void deactivate() { // deallocate resources here that are no longer needed and // should be reset when activating this binding again } /** * @{inheritDoc */ @Override protected long getRefreshInterval() { return refreshInterval; } /** * @{inheritDoc */ @Override protected String getName() { return "Enigma2 Refresh Service"; } /** * @{inheritDoc */ @Override protected void execute() { logger.debug("execute() called"); for (Enigma2BindingProvider provider : providers) { Collection<String> names = provider.getItemNames(); for (String name : names) { logger.debug("Name {}", name); Enigma2BindingConfig bindingConfig = provider.getBindingConfigFor(name); String deviceId = bindingConfig.getDeviceId(); /* * check if a device with this id is already configured */ if (enigmaNodes.containsKey(deviceId)) { Enigma2Node node = enigmaNodes.get(deviceId); /* * yes, there is a device with this id, now update it */ String value = null; switch (bindingConfig.getCmdId()) { case VOLUME: value = node.getVolume(); break; case CHANNEL: value = node.getChannel(); break; case POWERSTATE: value = node.getOnOff(); break; case PAUSE: logger.debug("Querying the player state (Play/Pause) is currently not supported"); break; case MUTE: value = node.getMuteUnmute(); break; case DOWNMIX: value = node.getDownmix(); default: break; } if (value != null) { postUpdate(provider, bindingConfig.getItem(), value); } } else { logger.error("Unknown deviceId \"{}\"", deviceId); } } } } private void postUpdate(Enigma2BindingProvider provider, Item item, final String value) { Class<? extends Item> itemType = provider.getItemType(item.getName()); State state = createState(itemType, value); if (state != null) { if (item instanceof GenericItem) { ((GenericItem) item).setState(state); } eventPublisher.postUpdate(item.getName(), state); } } private State createState(Class<? extends Item> itemType, String transformedResponse) { try { if (itemType.isAssignableFrom(NumberItem.class)) { return DecimalType.valueOf(transformedResponse); } else if (itemType.isAssignableFrom(SwitchItem.class)) { return OnOffType.valueOf(transformedResponse); } else if (itemType.isAssignableFrom(DimmerItem.class)) { return PercentType.valueOf(transformedResponse); } else { return StringType.valueOf(transformedResponse); } } catch (Exception e) { logger.debug("Couldn't create state of type '{}' for value '{}'", itemType, transformedResponse); return StringType.valueOf(transformedResponse); } } /** * @{inheritDoc */ @Override protected void internalReceiveCommand(String itemName, Command command) { logger.debug("internalReceiveCommand() called, itemName={}, command={}", itemName, command); /* * do we have a binding for this item at all? */ if (providesBindingFor(itemName)) { /* * go through all the providers and look for a BindingConfig */ for (Enigma2BindingProvider provider : providers) { Enigma2BindingConfig bindingConfig = provider.getBindingConfigFor(itemName); if (bindingConfig == null) { continue; } /* * Found one */ Enigma2Node node = enigmaNodes.get(bindingConfig.getDeviceId()); if (node == null) { logger.error("Invalid deviceId {}", bindingConfig.getDeviceId()); } switch (bindingConfig.getCmdId()) { case VOLUME: node.setVolume(command); break; case CHANNEL: node.setChannel(command); break; case PAUSE: node.sendPlayPause(command); break; case MUTE: node.sendMuteUnmute(command); break; case REMOTECONTROL: node.sendRcCommand(command, bindingConfig.getCmdValue()); break; case POWERSTATE: node.sendOnOff(command, Enigma2PowerState.STANDBY); break; case DOWNMIX: node.setDownmix(command); break; default: logger.error("Unknown cmdId \"{}\"", bindingConfig.getCmdId()); } } } else { logger.trace("No provider found for this item"); } } protected void addBindingProvider(Enigma2BindingProvider bindingProvider) { super.addBindingProvider(bindingProvider); } protected void removeBindingProvider(Enigma2BindingProvider bindingProvider) { super.removeBindingProvider(bindingProvider); } /** * {@inheritDoc} */ @Override public void updated(Dictionary<String, ?> config) throws ConfigurationException { if (config != null) { String refreshIntervalString = (String) config.get("refresh"); if (StringUtils.isNotBlank(refreshIntervalString)) { refreshInterval = Long.parseLong(refreshIntervalString); } Enumeration<String> keys = config.keys(); while (keys.hasMoreElements()) { String key = keys.nextElement(); String[] keyElements = key.split(":"); String deviceId = keyElements[0]; if (keyElements.length >= 2) { Enigma2Node node = enigmaNodes.get(deviceId); if (node == null) { node = new Enigma2Node(); enigmaNodes.put(deviceId, node); } String option = keyElements[1]; if (option.equals("hostname")) { node.setHostName((String) config.get(key)); } else if (option.equals("username")) { node.setUserName((String) config.get(key)); } else if (option.equals("password")) { node.setPassword((String) config.get(key)); } } } setProperlyConfigured(checkProperlyConfigured()); } } private boolean checkProperlyConfigured() { for (Enigma2Node node : this.enigmaNodes.values()) { if (!node.properlyConfigured()) { return false; } } return true; } }