<commit_before>/**
 * Copyright (c) 2010-2016, openHAB.org and others.
 *
 * 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.urtsi.internal;

import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.openhab.binding.urtsi.UrtsiBindingProvider;
import org.openhab.core.binding.AbstractBinding;
import org.openhab.core.library.types.StopMoveType;
import org.openhab.core.library.types.UpDownType;
import org.openhab.core.types.Command;
import org.openhab.core.types.State;
import org.openhab.core.types.Type;
import org.openhab.model.item.binding.BindingConfigParseException;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Sets;

/**
 * Main implementation of the Somfy URTSI II Binding. This binding is
 * responsible for delegating the received commands and updates to the
 * {@link UrtsiDevice}.
 *
 * @author <NAME>
 * @since 1.3.0
 *
 */
public class UrtsiBinding extends AbstractBinding<UrtsiBindingProvider>implements ManagedService {

    private static final String GNU_IO_RXTX_SERIAL_PORTS = "gnu.io.rxtx.SerialPorts";

    private final static Logger logger = LoggerFactory.getLogger(UrtsiBinding.class);

    private final static String COMMAND_UP = "U";
    private final static String COMMAND_DOWN = "D";
    private final static String COMMAND_STOP = "S";

    private final static String CONFIG_PORT = "port";
    private final static String CONFIG_INTERVAL = "interval";

    private final static Pattern EXTRACT_URTSI_CONFIG_PATTERN = Pattern
            .compile("^(.*?)\\.(" + CONFIG_PORT + "|" + CONFIG_INTERVAL + ")$");

    /**
     * Maps the device id to a URTSI device. This is needed if you use multiple
     * ports for multiple urtsi devices.
     */
    private final Map<String, UrtsiDevice> idToDeviceMap = new HashMap<String, UrtsiDevice>();

    /**
     * The method determines the appropriate
     * {@link org.openhab.core.binding.BindingProvider} and uses it to get the
     * corresponding URTSI device and channel. Bases on the given type a command
     * is send to the device.
     *
     * @param itemName
     *            name of the item
     * @param type
     *            Type of the command or status update
     * @return Returns true, if the command has been executed successfully.
     *         Returns false otherwise.
     * @throws BindingConfigParseException
     */
    private boolean sendToUrtsi(String itemName, Type type) {
        UrtsiBindingProvider provider = null;
        if (!providers.isEmpty()) {
            provider = providers.iterator().next();
        }
        if (provider == null) {
            logger.error("doesn't find matching binding provider [itemName={}, type={}]", itemName, type);
            return false;
        }
        String urtsiDeviceId = provider.getDeviceId(itemName);
        UrtsiDevice urtsiDevice = idToDeviceMap.get(urtsiDeviceId);

        if (urtsiDevice == null) {
            logger.error("No serial port has been configured for urtsi device id '{}'", urtsiDeviceId);
            return false;
        }

        int channel = provider.getChannel(itemName);
        int address = provider.getAddress(itemName);

        logger.debug("Send to URTSI for item: {}; Type: {}", itemName, type);
        String actionKey = null;
        if (type instanceof UpDownType) {
            switch ((UpDownType) type) {
                case UP:
                    actionKey = COMMAND_UP;
                    break;
                case DOWN:
                    actionKey = COMMAND_DOWN;
                    break;
            }
        } else if (type instanceof StopMoveType) {
            switch ((StopMoveType) type) {
                case STOP:
                    actionKey = COMMAND_STOP;
                    break;
                default:
                    break;
            }
        }

        logger.debug("Action key: {}", actionKey);
        if (actionKey != null) {
            String channelString = String.format("%02d", channel);
            String addressString = String.format("%02d", address);
            String command = addressString + channelString + actionKey;
            boolean executedSuccessfully = urtsiDevice.writeString(command);
            if (!executedSuccessfully) {
                logger.warn("Command has not been processed [itemName={}, command={}]", itemName, command);
            }
            return executedSuccessfully;
        }
        return false;
    }

    /**
     * The method delegates the received command to the URTSI device and updates
     * the item's state, if the command has been executed successfully.
     */
    @Override
    protected void internalReceiveCommand(String itemName, Command command) {
        logger.debug("Received command for {}! Command: {}", itemName, command);
        boolean executedSuccessfully = sendToUrtsi(itemName, command);
        if (executedSuccessfully && command instanceof State) {
            eventPublisher.postUpdate(itemName, (State) command);
        }
    }

    /**
     * With openHAB 1.7.0 the state-update is not passed to the URTSI device anymore as this let to multiple actions in
     * the past.
     *
     */
    @Override
    protected void internalReceiveUpdate(String itemName, State newState) {
        logger.debug("Received update for {}! New state: {}", itemName, newState);
    }

    /**
     * Parses the global configuration file.
     * Expected values:
     * urtsi.<deviceid>.port=<serialport>
     * urtsi.<deviceid>.interval=<interval> (optional, default: 100)
     */
    @Override
    public void updated(Dictionary<String, ?> config) throws ConfigurationException {

        if (config != null) {
            Map<String, String> errorMessages = new LinkedHashMap<String, String>();<commit_msg>urtsi<commit_after>/**
 * Copyright (c) 2010-2016, openHAB.org and others.
 *
 * 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.urtsi.internal;

import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.openhab.binding.urtsi.UrtsiBindingProvider;
import org.openhab.core.binding.AbstractBinding;
import org.openhab.core.library.types.StopMoveType;
import org.openhab.core.library.types.UpDownType;
import org.openhab.core.types.Command;
import org.openhab.core.types.State;
import org.openhab.core.types.Type;
import org.openhab.model.item.binding.BindingConfigParseException;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Sets;

/**
 * Main implementation of the Somfy URTSI II Binding. This binding is
 * responsible for delegating the received commands and updates to the
 * {@link UrtsiDevice}.
 *
 * @author <NAME>
 * @since 1.3.0
 *
 */
public class UrtsiBinding extends AbstractBinding<UrtsiBindingProvider>implements ManagedService {

    private static final String GNU_IO_RXTX_SERIAL_PORTS = "gnu.io.rxtx.SerialPorts";

    private final static Logger logger = LoggerFactory.getLogger(UrtsiBinding.class);

    private final static String COMMAND_UP = "U";
    private final static String COMMAND_DOWN = "D";
    private final static String COMMAND_STOP = "S";

    private final static String CONFIG_PORT = "port";
    private final static String CONFIG_INTERVAL = "interval";

    private final static Pattern EXTRACT_URTSI_CONFIG_PATTERN = Pattern
            .compile("^(.*?)\\.(" + CONFIG_PORT + "|" + CONFIG_INTERVAL + ")$");

    /**
     * Maps the device id to a URTSI device. This is needed if you use multiple
     * ports for multiple urtsi devices.
     */
    private final Map<String, UrtsiDevice> idToDeviceMap = new HashMap<String, UrtsiDevice>();

    /**
     * The method determines the appropriate
     * {@link org.openhab.core.binding.BindingProvider} and uses it to get the
     * corresponding URTSI device and channel. Bases on the given type a command
     * is send to the device.
     *
     * @param itemName
     *            name of the item
     * @param type
     *            Type of the command or status update
     * @return Returns true, if the command has been executed successfully.
     *         Returns false otherwise.
     * @throws BindingConfigParseException
     */
    private boolean sendToUrtsi(String itemName, Type type) {
        UrtsiBindingProvider provider = null;
        if (!providers.isEmpty()) {
            provider = providers.iterator().next();
        }
        if (provider == null) {
            logger.error("doesn't find matching binding provider [itemName={}, type={}]", itemName, type);
            return false;
        }
        String urtsiDeviceId = provider.getDeviceId(itemName);
        UrtsiDevice urtsiDevice = idToDeviceMap.get(urtsiDeviceId);

        if (urtsiDevice == null) {
            logger.error("No serial port has been configured for urtsi device id '{}'", urtsiDeviceId);
            return false;
        }

        int channel = provider.getChannel(itemName);
        int address = provider.getAddress(itemName);

        logger.debug("Send to URTSI for item: {}; Type: {}", itemName, type);
        String actionKey = null;
        if (type instanceof UpDownType) {
            switch ((UpDownType) type) {
                case UP:
                    actionKey = COMMAND_UP;
                    break;
                case DOWN:
                    actionKey = COMMAND_DOWN;
                    break;
            }
        } else if (type instanceof StopMoveType) {
            switch ((StopMoveType) type) {
                case STOP:
                    actionKey = COMMAND_STOP;
                    break;
                default:
                    break;
            }
        }

        logger.debug("Action key: {}", actionKey);
        if (actionKey != null) {
            String channelString = String.format("%02d", channel);
            String addressString = String.format("%02d", address);
            String command = addressString + channelString + actionKey;
            boolean executedSuccessfully = urtsiDevice.writeString(command);
            if (!executedSuccessfully) {
                logger.warn("Command has not been processed [itemName={}, command={}]", itemName, command);
            }
            return executedSuccessfully;
        }
        return false;
    }

    /**
     * The method delegates the received command to the URTSI device and updates
     * the item's state, if the command has been executed successfully.
     */
    @Override
    protected void internalReceiveCommand(String itemName, Command command) {
        logger.debug("Received command for {}! Command: {}", itemName, command);
        boolean executedSuccessfully = sendToUrtsi(itemName, command);
        if (executedSuccessfully && command instanceof State) {
            eventPublisher.postUpdate(itemName, (State) command);
        }
    }

    /**
     * With openHAB 1.7.0 the state-update is not passed to the URTSI device anymore as this let to multiple actions in
     * the past.
     *
     */
    @Override
    protected void internalReceiveUpdate(String itemName, State newState) {
        logger.debug("Received update for {}! New state: {}", itemName, newState);
    }

    protected void addBindingProvider(UrtsiBindingProvider bindingProvider) {
        super.addBindingProvider(bindingProvider);
    }

    protected void removeBindingProvider(UrtsiBindingProvider bindingProvider) {
        super.removeBindingProvider(bindingProvider);
    }

    /**
     * Parses the global configuration file.
     * Expected values:
     * urtsi.<deviceid>.port=<serialport>
     * urtsi.<deviceid>.interval=<interval> (optional, default: 100)
     */
    @Override
    public void updated(Dictionary<String, ?> config) throws ConfigurationException {

        if (config != null) {
            Map<String, String> errorMessages = new LinkedHashMap<String, String>();
{'fraction_non_alphanumeric': 0.09596344249809596, 'fraction_numerical': 0.004112718964204113, 'mean_word_length': 2.6853774908784733, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4363191', 'n_tokens_mistral': 3629, 'n_tokens_neox': 3490, 'n_words': 1027}