001package com.pi4j.util;
002
003/*
004 * #%L
005 * **********************************************************************
006 * ORGANIZATION  :  Pi4J
007 * PROJECT       :  Pi4J :: Java Library (Core)
008 * FILENAME      :  CommandArgumentParser.java
009 *
010 * This file is part of the Pi4J project. More information about
011 * this project can be found here:  https://www.pi4j.com/
012 * **********************************************************************
013 * %%
014 * Copyright (C) 2012 - 2019 Pi4J
015 * %%
016 * This program is free software: you can redistribute it and/or modify
017 * it under the terms of the GNU Lesser General Public License as
018 * published by the Free Software Foundation, either version 3 of the
019 * License, or (at your option) any later version.
020 *
021 * This program is distributed in the hope that it will be useful,
022 * but WITHOUT ANY WARRANTY; without even the implied warranty of
023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
024 * GNU General Lesser Public License for more details.
025 *
026 * You should have received a copy of the GNU General Lesser Public
027 * License along with this program.  If not, see
028 * <http://www.gnu.org/licenses/lgpl-3.0.html>.
029 * #L%
030 */
031
032import com.pi4j.io.gpio.Pin;
033import com.pi4j.io.gpio.PinProvider;
034import com.pi4j.io.gpio.PinPullResistance;
035import com.pi4j.io.serial.*;
036
037import java.lang.reflect.Method;
038
039/**
040 *
041 */
042public class CommandArgumentParser {
043
044    /**
045     * This utility method searches for "--pin (#)" or "-p (#)" in the command
046     * arguments array and returns a Pin instance based on the pin
047     * address/number specified.
048     *
049     * @param pinProviderClass pin provider class to get pin instance from
050     * @param defaultPin default pin instance to use if no --pin argument is found
051     * @param args the argument array to search in
052     * @return GPIO pin instance
053     */
054    public static Pin getPin(Class<? extends PinProvider> pinProviderClass, Pin defaultPin, String ... args){
055        // search all arguments for the "--pin" or "-p" option
056        // we skip the last argument in the array because we expect a value defined after the option designator
057        for(int index = 0; index < (args.length-1); index++){
058            if(args[index].toLowerCase().equals("--pin") ||
059               args[index].toLowerCase().equals("-p")){
060                try {
061                    int pinAddress = Integer.parseInt(args[index+1]);
062                    Method m = pinProviderClass.getDeclaredMethod("getPinByAddress", int.class);
063                    Object pin = m.invoke(null, pinAddress);
064                    return (Pin)pin;
065                }
066                catch(Exception ex){
067                    System.err.println(ex.getMessage());
068                }
069            }
070        }
071        return defaultPin;
072    }
073
074    /**
075     * This utility method searches for "--pull (up|down|off)", "--l (up|down|off)", "--up", or "--down" in the command
076     * arguments array and returns a PinPullResistance instance based on the option
077     * value provided.
078     *
079     * @param defaultPull default pin pull resistance to apply if no option/argument is found
080     * @param args the argument array to search in
081     * @return pill pull resistance enum
082     */
083    public static PinPullResistance getPinPullResistance(PinPullResistance defaultPull, String ... args){
084
085        // search all arguments for the argument option designators
086        for(int index = 0; index < args.length; index++){
087
088            if(args[index].toLowerCase().equals("--up")){
089                return PinPullResistance.PULL_UP;
090            }
091            else if(args[index].toLowerCase().equals("--down")){
092                return PinPullResistance.PULL_DOWN;
093            }
094            else if(args[index].toLowerCase().equals("--pull") ||
095                    args[index].toLowerCase().equals("-l")){
096                // if using this option designator, we must have an additional
097                // argument in the array to read the value from
098                if(index < (args.length-1)){
099                    String pull = args[index+1].toLowerCase();
100                    if(pull.equals("up")){
101                        return PinPullResistance.PULL_UP;
102                    }
103                    else if(pull.equals("1")){
104                        return PinPullResistance.PULL_UP;
105                    }
106                    else if(pull.equals("down")){
107                        return PinPullResistance.PULL_DOWN;
108                    }
109                    else if(pull.equals("0")){
110                        return PinPullResistance.PULL_DOWN;
111                    }
112                    else{
113                        return PinPullResistance.OFF;
114                    }
115                }
116            }
117        }
118        return defaultPull;
119    }
120
121    /**
122     * This utility method searches for the following options:
123     *
124     *   "--device (device-path)"                   [DEFAULT: /dev/ttyAMA0]
125     *   "--baud (baud-rate)"                       [DEFAULT: 38400]
126     *   "--data-bits (5|6|7|8)"                    [DEFAULT: 8]
127     *   "--parity (none|odd|even)"                 [DEFAULT: none]
128     *   "--stop-bits (1|2)"                        [DEFAULT: 1]
129     *   "--flow-control (none|hardware|software)"  [DEFAULT: none]
130     *
131     * in the arguments array and returns a SerialConfig instance based on the option
132     * values detected.
133     *
134     * @param defaultConfig default serial configuration to apply if no option/arguments are found
135     * @param args the argument array to search in
136     * @return serial config object
137     */
138    public static SerialConfig getSerialConfig(SerialConfig defaultConfig, String ... args){
139
140        // search all arguments for the argument option designators
141        // we skip the last argument in the array because we expect a value defined after each option designator
142        for(int index = 0; index < (args.length-1); index++){
143
144            // "--device (device-path)"                   [DEFAULT: /dev/ttyAMA0]
145            if(args[index].toLowerCase().equals("--device")){
146                defaultConfig.device(args[index+1]);
147                index++;
148                continue;
149            }
150
151            // "--baud (baud-rate)"                       [DEFAULT: 38400]
152            if(args[index].toLowerCase().equals("--baud")){
153                defaultConfig.baud(Baud.getInstance(Integer.parseInt(args[index + 1])));
154                index++;
155                continue;
156            }
157
158            // "--data-bits (5|6|7|8)"                    [DEFAULT: 8]
159            if(args[index].toLowerCase().equals("--data-bits")){
160                defaultConfig.dataBits(DataBits.getInstance(Integer.parseInt(args[index + 1])));
161                index++;
162                continue;
163            }
164
165            // "--parity (none|odd|even)"                 [DEFAULT: none]
166            if(args[index].toLowerCase().equals("--parity")){
167                defaultConfig.parity(Parity.getInstance(args[index + 1]));
168                index++;
169                continue;
170            }
171
172            // "--stop-bits (1|2)"                        [DEFAULT: 1]
173            if(args[index].toLowerCase().equals("--stop-bits")){
174                defaultConfig.stopBits(StopBits.getInstance(Integer.parseInt(args[index + 1])));
175                index++;
176                continue;
177            }
178
179            // "--flow-control (none|hardware|software)"  [DEFAULT: none]
180            if(args[index].toLowerCase().equals("--flow-control")){
181                defaultConfig.flowControl(FlowControl.getInstance(args[index + 1]));
182                index++;
183                continue;
184            }
185        }
186        return defaultConfig;
187    }
188}