org.openhab.io.transport.cul.internal.serial.CULSerialConfigFactory.java Source code

Java tutorial

Introduction

Here is the source code for org.openhab.io.transport.cul.internal.serial.CULSerialConfigFactory.java

Source

/**
 * Copyright (c) 2010-2019 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.io.transport.cul.internal.serial;

import java.util.Arrays;
import java.util.Collections;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang.StringUtils;
import org.openhab.io.transport.cul.CULMode;
import org.openhab.io.transport.cul.internal.CULConfig;
import org.openhab.io.transport.cul.internal.CULConfigFactory;
import org.osgi.service.cm.ConfigurationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import gnu.io.SerialPort;

/**
 * Configuration factory for serial device handler implementation.
 *
 * @author Patrick Ruckstuhl
 * @since 1.9.0
 */
public class CULSerialConfigFactory implements CULConfigFactory {
    private final static Logger logger = LoggerFactory.getLogger(CULSerialConfigFactory.class);
    private static final Map<String, Integer> validParitiesMap;
    private static final List<Integer> validBaudrateMap;

    static {
        Map<String, Integer> parities = new HashMap<String, Integer>();
        parities.put("EVEN", SerialPort.PARITY_EVEN);
        parities.put("ODD", SerialPort.PARITY_ODD);
        parities.put("MARK", SerialPort.PARITY_MARK);
        parities.put("NONE", SerialPort.PARITY_NONE);
        parities.put("SPACE", SerialPort.PARITY_SPACE);
        validParitiesMap = Collections.unmodifiableMap(parities);

        Integer baudrates[] = { 75, 110, 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200 };
        validBaudrateMap = Collections.unmodifiableList(Arrays.asList(baudrates));
    }

    private final static String KEY_BAUDRATE = "baudrate";
    private final static String KEY_PARITY = "parity";

    @Override
    public CULConfig create(String deviceType, String deviceAddress, CULMode mode, Dictionary<String, ?> config)
            throws ConfigurationException {
        int baudRate = 9600;
        final String configuredBaudRate = (String) config.get(KEY_BAUDRATE);
        Integer tmpBaudRate = baudrateFromConfig(configuredBaudRate);
        if (tmpBaudRate != null) {
            baudRate = tmpBaudRate;
            logger.info("Update config, {} = {}", KEY_BAUDRATE, baudRate);
        }

        int parityMode = SerialPort.PARITY_EVEN;
        final String configuredParity = (String) config.get(KEY_PARITY);
        Integer parsedParityNumber = parityFromConfig(configuredParity);
        if (parsedParityNumber != null) {
            parityMode = parsedParityNumber;
            logger.info("Update config, {} = {} ({})", KEY_PARITY, convertParityModeToString(parityMode),
                    parityMode);
        }

        return new CULSerialConfig(deviceType, deviceAddress, mode, baudRate, parityMode);
    }

    private Integer parityFromConfig(final String configuredParity) {
        if (StringUtils.isNotBlank(configuredParity)) {
            try {
                if (isValidParity(configuredParity)) {
                    return validParitiesMap.get(configuredParity.toUpperCase());
                } else { // allow literal parity assignment?
                    int parsedParityNumber = Integer.parseInt(configuredParity);
                    if (isValidParity(parsedParityNumber)) {
                        return parsedParityNumber;
                    } else {
                        logger.error("The configured '{}' value is invalid. The value '{}' has to be one of {}.",
                                KEY_PARITY, parsedParityNumber, validParitiesMap.keySet());
                    }
                }
            } catch (NumberFormatException e) {
                logger.error("Error parsing config key '{}'. Use one of {}.", KEY_PARITY,
                        validParitiesMap.keySet());
            }
        }
        return null;
    }

    /**
     * calculate baudrate from config String
     *
     * @param configuredBaudRate
     * @return baud Rate or null if failed
     */
    private Integer baudrateFromConfig(final String configuredBaudRate) {
        if (StringUtils.isNotBlank(configuredBaudRate)) {
            try {
                int tmpBaudRate = Integer.parseInt(configuredBaudRate);
                if (validBaudrateMap.contains(tmpBaudRate)) {
                    return tmpBaudRate;
                } else {
                    logger.error(
                            "Error parsing config parameter '{}'. Value = {} is not a valid baudrate. Value must be in [75, 110, 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200]",
                            KEY_BAUDRATE, tmpBaudRate);
                }
            } catch (NumberFormatException e) {
                logger.error("Error parsing config parameter '{}' to integer. Value = {}", KEY_BAUDRATE,
                        configuredBaudRate);
            }

        }
        return null;

    }

    /**
     * Checks if mode is a valid input for 'SerialPort' - class
     *
     * @param mode
     * @return true if valid
     */
    private boolean isValidParity(int mode) {
        return validParitiesMap.containsValue(mode);
    }

    /**
     * Checks if mode is a valid input for 'SerialPort' - class
     *
     * @param mode
     * @return true if valid
     */
    private boolean isValidParity(String mode) {
        return validParitiesMap.containsKey(mode.toUpperCase());
    }

    /**
     * converts modes integer representation into a readable sting
     *
     * @param mode
     * @return text if mode was valid, otherwise "invalid mode"
     */
    private String convertParityModeToString(int mode) {
        if (validParitiesMap.containsValue(mode)) {
            for (Entry<String, Integer> parity : validParitiesMap.entrySet()) {
                if (parity.getValue().equals(mode)) {
                    return parity.getKey();
                }
            }
        }
        return "invalid mode";
    }

}