diff --git a/pi4j-core/src/main/java/com/pi4j/internal/ProviderAliases.java b/pi4j-core/src/main/java/com/pi4j/internal/ProviderAliases.java index 95d216fd..50defd2b 100644 --- a/pi4j-core/src/main/java/com/pi4j/internal/ProviderAliases.java +++ b/pi4j-core/src/main/java/com/pi4j/internal/ProviderAliases.java @@ -29,6 +29,7 @@ import com.pi4j.io.gpio.analog.AnalogInputProvider; import com.pi4j.io.gpio.analog.AnalogOutputProvider; import com.pi4j.io.gpio.digital.DigitalInputProvider; +import com.pi4j.io.gpio.digital.DigitalMultipurposeProvider; import com.pi4j.io.gpio.digital.DigitalOutputProvider; import com.pi4j.io.i2c.I2CProvider; import com.pi4j.io.pwm.PwmProvider; @@ -107,6 +108,17 @@ default T dout() throws ProviderException{ return digitalOutput(); } + /** + *

dmulti.

+ * + * @param a T object. + * @return a T object. + * @throws ProviderException if any. + */ + default T dmulti() throws ProviderException{ + return digitalMultipurpose(); + } + /** *

analogInput.

* @@ -151,6 +163,17 @@ default T digitalOutput() throws ProviderExcep return this.provider(IOType.DIGITAL_OUTPUT); } + /** + *

digitalMultipurpose.

+ * + * @param a T object. + * @return a T object. + * @throws ProviderException if any. + */ + default T digitalMultipurpose() throws ProviderException{ + return this.provider(IOType.DIGITAL_MULTIPURPOSE); + } + /** *

pwm.

* diff --git a/pi4j-core/src/main/java/com/pi4j/io/IOType.java b/pi4j-core/src/main/java/com/pi4j/io/IOType.java index 492468d4..9f1750c5 100644 --- a/pi4j-core/src/main/java/com/pi4j/io/IOType.java +++ b/pi4j-core/src/main/java/com/pi4j/io/IOType.java @@ -58,6 +58,7 @@ public enum IOType { ANALOG_OUTPUT(AnalogOutputProvider.class, AnalogOutput.class, AnalogOutputConfig.class, AnalogOutputConfigBuilder.class), DIGITAL_INPUT(DigitalInputProvider.class, DigitalInput.class, DigitalInputConfig.class, DigitalInputConfigBuilder.class), DIGITAL_OUTPUT(DigitalOutputProvider.class, DigitalOutput.class, DigitalOutputConfig.class, DigitalOutputConfigBuilder.class), + DIGITAL_MULTIPURPOSE(DigitalMultipurposeProvider.class, DigitalMultipurpose.class, DigitalMultipurposeConfig.class, DigitalMultipurposeConfigBuilder.class), PWM(PwmProvider.class, Pwm.class, PwmConfig.class, PwmConfigBuilder.class), I2C(I2CProvider.class, com.pi4j.io.i2c.I2C.class, I2CConfig.class, I2CConfigBuilder.class), SPI(SpiProvider.class, Spi.class, I2CConfig.class, I2CConfigBuilder.class), @@ -302,6 +303,15 @@ public static IOType parse(String ioType) { if(ioType.startsWith("digital o")) return DIGITAL_OUTPUT; if(ioType.equalsIgnoreCase("dout")) return DIGITAL_OUTPUT; + // DIGITAL MULTIPURPOSE + if(ioType.startsWith("digital.m")) return DIGITAL_MULTIPURPOSE; + if(ioType.startsWith("digital-m")) return DIGITAL_MULTIPURPOSE; + if(ioType.startsWith("digital_m")) return DIGITAL_MULTIPURPOSE; + if(ioType.startsWith("digital m")) return DIGITAL_MULTIPURPOSE; + if(ioType.equalsIgnoreCase("dmulti")) return DIGITAL_MULTIPURPOSE; + if(ioType.equalsIgnoreCase("dmultipurpose")) return DIGITAL_MULTIPURPOSE; + if(ioType.equalsIgnoreCase("dmulti-purpose")) return DIGITAL_MULTIPURPOSE; + // PWM if(ioType.equalsIgnoreCase("pwm")) return PWM; if(ioType.equalsIgnoreCase("p.w.m")) return PWM; @@ -340,12 +350,3 @@ public static IOType parse(String ioType) { throw new IllegalArgumentException("Unknown IO TYPE: " + ioType); } } - -// ANALOG_INPUT(AnalogInputProvider.class, AnalogInput.class, AnalogInputConfig.class, AnalogInputConfigBuilder.class), -// ANALOG_OUTPUT(AnalogOutputProvider.class, AnalogOutput.class, AnalogOutputConfig.class, AnalogOutputConfigBuilder.class), -// DIGITAL_INPUT(DigitalInputProvider.class, DigitalInput.class, DigitalInputConfig.class, DigitalInputConfigBuilder.class), -// DIGITAL_OUTPUT(DigitalOutputProvider.class, DigitalOutput.class, DigitalOutputConfig.class, DigitalOutputConfigBuilder.class), -// PWM(PwmProvider.class, Pwm.class, PwmConfig.class, PwmConfigBuilder.class), -// I2C(I2CProvider.class, com.pi4j.io.i2c.I2C.class, I2CConfig.class, I2CConfigBuilder.class), -// SPI(SpiProvider.class, Spi.class, I2CConfig.class, I2CConfigBuilder.class), -// SERIAL(SerialProvider.class, Serial.class, SerialConfig.class, SerialConfigBuilder.class); diff --git a/pi4j-core/src/main/java/com/pi4j/io/InputOutput.java b/pi4j-core/src/main/java/com/pi4j/io/InputOutput.java new file mode 100644 index 00000000..1315c224 --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/io/InputOutput.java @@ -0,0 +1,39 @@ +package com.pi4j.io; + +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: LIBRARY :: Java Library (CORE) + * FILENAME : InputOutput.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + + +/** + *

Input interface.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public interface InputOutput extends Input, Output { + // MARKER INTERFACE +} diff --git a/pi4j-core/src/main/java/com/pi4j/io/exception/IOModeException.java b/pi4j-core/src/main/java/com/pi4j/io/exception/IOModeException.java new file mode 100644 index 00000000..9630dd92 --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/io/exception/IOModeException.java @@ -0,0 +1,61 @@ +package com.pi4j.io.exception; + +/* + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: LIBRARY :: Java Library (CORE) + * FILENAME : IOModeException.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + + +/** + *

+ * This exception is thrown if a platform assignment is attempted when a + * platform instance has already been assigned. + *

+ * + * @see http://www.pi4j.com/ + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public class IOModeException extends IOException { + + /** + * Default Constructor + * + * @param message a {@link String} object. + */ + public IOModeException(String message){ + super(message); + } + + /** + * Alternate Constructor + * + * @param error a int. + */ + public IOModeException(int error){ + super("I/O MODE ERROR: " + error); + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/Digital.java b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/Digital.java index 88f4131e..47aae0f4 100644 --- a/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/Digital.java +++ b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/Digital.java @@ -44,6 +44,12 @@ public interface Digital { + /** + * Get digital mode (input|output) + * @return digital mode (input|output) + */ + DigitalMode mode(); + /** *

state.

* diff --git a/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalInput.java b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalInput.java index a0c8c1ba..443c3395 100644 --- a/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalInput.java +++ b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalInput.java @@ -55,4 +55,10 @@ static DigitalInputConfigBuilder newConfigBuilder(Context context){ * @return a {@link com.pi4j.io.gpio.digital.PullResistance} object. */ default PullResistance pull() { return config().pull(); } + + /** + * Get digital mode (input|output) + * @return INPUT + */ + default DigitalMode mode() { return DigitalMode.INPUT; } } diff --git a/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMode.java b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMode.java new file mode 100644 index 00000000..ce90b599 --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMode.java @@ -0,0 +1,251 @@ +package com.pi4j.io.gpio.digital; + +import java.util.EnumSet; + +/* + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: LIBRARY :: Java Library (CORE) + * FILENAME : DigitalMode.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +/** + * Digital Mode Enumerations + * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public enum DigitalMode { + + UNKNOWN(-1, "UNKNOWN"), + INPUT(0, "INPUT"), + OUTPUT(1, "OUTPUT"); + + private final Integer value; + private final String name; + + private DigitalMode(Integer value, String name) { + this.value = value; + this.name = name; + } + + /** + *

isInput.

+ * + * @return a boolean. + */ + public boolean isInput() { + return (this == INPUT); + } + + /** + *

input.

+ * + * @return a boolean. + */ + public boolean input() { + return (this.isInput()); + } + + /** + *

isOutput.

+ * + * @return a boolean. + */ + public boolean isOutput() { + return (this == OUTPUT); + } + + /** + *

output.

+ * + * @return a boolean. + */ + public boolean output() { + return (this.isOutput()); + } + + /** + *

value.

+ * + * @return a {@link Number} object. + */ + public Number value() { + return getValue(); + } + + /** + *

Getter for the field value.

+ * + * @return a {@link Number} object. + */ + public Number getValue() { + return value; + } + + /** + *

Getter for the field name.

+ * + * @return a {@link String} object. + */ + public String getName() { + return name; + } + + /** + *

equals.

+ * + * @param mode a {@link DigitalMode} object. + * @return a boolean. + */ + public boolean equals(DigitalMode mode) { + return this == mode; + } + + /** + *

equals.

+ * + * @param mode a {@link Number} object. + * @return a boolean. + */ + public boolean equals(Number mode) { + return this == DigitalMode.getMode(mode); + } + + public boolean equals(byte mode){ + return equals(DigitalMode.getMode(mode)); + } + /** + *

equals.

+ * + * @param mode a short. + * @return a boolean. + */ + public boolean equals(short mode){ + return equals(DigitalMode.getMode(mode)); + } + + /** + *

equals.

+ * + * @param mode a int. + * @return a boolean. + */ + public boolean equals(int mode){ + return equals(DigitalMode.getMode(mode)); + } + + /** + *

equals.

+ * + * @param mode a long. + * @return a boolean. + */ + public boolean equals(long mode){ + return equals(DigitalMode.getMode(mode)); + } + + /** + *

equals.

+ * + * @param mode a float. + * @return a boolean. + */ + public boolean equals(float mode){ + return equals(DigitalMode.getMode(mode)); + } + + /** + *

equals.

+ * + * @param mode a double. + * @return a boolean. + */ + public boolean equals(double mode){ + return equals(DigitalMode.getMode(mode)); + } + + /** {@inheritDoc} */ + @Override + public String toString() { + return name; + } + + /** + *

state.

+ * + * @param mode a {@link Number} object. + * @return a {@link DigitalMode} object. + */ + public static DigitalMode state(Number mode) { + return getMode(mode); + } + + /** + *

getState.

+ * + * @param mode a {@link Number} object. + * @return a {@link DigitalMode} object. + */ + public static DigitalMode getMode(Number mode) { + for (var item : DigitalMode.values()) { + if (item.getValue().intValue() == mode.intValue()) { + return item; + } + } + return null; + } + + /** + *

allStates.

+ * + * @return an array of {@link DigitalMode} objects. + */ + public static DigitalMode[] allStates() { + return DigitalMode.values(); + } + + /** + *

all.

+ * + * @return a {@link EnumSet} object. + */ + public static EnumSet all() { + return EnumSet.of(DigitalMode.INPUT, DigitalMode.OUTPUT); + } + + /** + *

parse.

+ * + * @param state a {@link String} object. + * @return a {@link DigitalMode} object. + */ + public static DigitalMode parse(String state) { + if(state.equalsIgnoreCase("0")) return DigitalMode.INPUT; + if(state.equalsIgnoreCase("1")) return DigitalMode.OUTPUT; + if(state.toLowerCase().startsWith("i")) return DigitalMode.INPUT; + if(state.toLowerCase().startsWith("o")) return DigitalMode.OUTPUT; + return DigitalMode.UNKNOWN; + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMultipurpose.java b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMultipurpose.java new file mode 100644 index 00000000..11a72d90 --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMultipurpose.java @@ -0,0 +1,425 @@ +package com.pi4j.io.gpio.digital; + +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: LIBRARY :: Java Library (CORE) + * FILENAME : DigitalMultipurpose.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + + +import com.pi4j.context.Context; +import com.pi4j.io.InputOutput; +import com.pi4j.io.OnOff; +import com.pi4j.io.exception.IOException; + +import java.util.concurrent.Callable; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +/** + *

DigitalInput interface.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public interface DigitalMultipurpose extends + Digital, + InputOutput, OnOff { + /** Constant DEFAULT_DEBOUNCE=10000 */ + long DEFAULT_DEBOUNCE = 10000; + + /** + *

newConfigBuilder.

+ * + * @param context {@link Context} + * @return a {@link DigitalInputConfigBuilder} object. + */ + static DigitalMultipurposeConfigBuilder newConfigBuilder(Context context){ + return DigitalMultipurposeConfigBuilder.newInstance(context); + } + + /** + *

pull.

+ * + * @return a {@link PullResistance} object. + */ + default PullResistance pull() { return config().pull(); } + + /** + * Get digital mode (input|output) + * @return digital mode (input|output) + */ + DigitalMode mode(); + + /** + * Set digital mode (input|output) + * @param mode DigitalMode (input|output) + * @return this I/O instance + */ + DigitalMultipurpose mode(DigitalMode mode) throws IOException; + + /** + * Set digital mode to INPUT + * @return this I/O instance + */ + default DigitalMultipurpose input() throws IOException { + return this.mode(DigitalMode.INPUT); + } + + /** + * Return TRUE if mode is set to INPUT + * @return 'true' if mode is INPUT; else 'false' + */ + default boolean isInput(){ + return this.mode().isInput(); + } + + /** + * Return TRUE if mode is set to OUTPUT + * @return 'true' if mode is OUTPUT; else 'false' + */ + default boolean isOutput(){ + return this.mode().isOutput(); + } + + /** + * Set digital mode to OUTPUT + * @return this I/O instance + */ + default DigitalMultipurpose output() throws IOException { + return this.mode(DigitalMode.OUTPUT); + } + + /** + *

state.

+ * + * @param state a {@link com.pi4j.io.gpio.digital.DigitalState} object. + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutput} object. + * @throws com.pi4j.io.exception.IOException if any. + */ + DigitalMultipurpose state(DigitalState state) throws IOException; + + /** + *

pulse.

+ * + * @param interval a int. + * @param unit a {@link java.util.concurrent.TimeUnit} object. + * @param state a {@link com.pi4j.io.gpio.digital.DigitalState} object. + * @param callback a {@link java.util.concurrent.Callable} object. + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutput} object. + * @throws com.pi4j.io.exception.IOException if any. + */ + DigitalMultipurpose pulse(int interval, TimeUnit unit, DigitalState state, Callable callback) throws IOException; + /** + *

pulseAsync.

+ * + * @param interval a int. + * @param unit a {@link java.util.concurrent.TimeUnit} object. + * @param state a {@link com.pi4j.io.gpio.digital.DigitalState} object. + * @param callback a {@link java.util.concurrent.Callable} object. + * @return a {@link java.util.concurrent.Future} object. + */ + Future pulseAsync(int interval, TimeUnit unit, DigitalState state, Callable callback); + /** + *

blink.

+ * + * @param delay a int. + * @param duration a int. + * @param unit a {@link java.util.concurrent.TimeUnit} object. + * @param state a {@link com.pi4j.io.gpio.digital.DigitalState} object. + * @param callback a {@link java.util.concurrent.Callable} object. + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutput} object. + */ + DigitalMultipurpose blink(int delay, int duration, TimeUnit unit, DigitalState state, Callable callback); + /** + *

blinkAsync.

+ * + * @param delay a int. + * @param duration a int. + * @param unit a {@link java.util.concurrent.TimeUnit} object. + * @param state a {@link com.pi4j.io.gpio.digital.DigitalState} object. + * @param callback a {@link java.util.concurrent.Callable} object. + * @return a {@link java.util.concurrent.Future} object. + */ + Future blinkAsync(int delay, int duration, TimeUnit unit, DigitalState state, Callable callback); + + /** + *

setState.

+ * + * @param state a boolean. + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutput} object. + * @throws com.pi4j.io.exception.IOException if any. + */ + default DigitalMultipurpose setState(boolean state) throws IOException { + return this.state(DigitalState.getState(state)); + } + /** + *

setState.

+ * + * @param state a byte. + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutput} object. + * @throws com.pi4j.io.exception.IOException if any. + */ + default DigitalMultipurpose setState(byte state) throws IOException { + return this.state(DigitalState.getState(state)); + } + /** + *

setState.

+ * + * @param state a short. + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutput} object. + * @throws com.pi4j.io.exception.IOException if any. + */ + default DigitalMultipurpose setState(short state) throws IOException { + return this.state(DigitalState.getState(state)); + } + /** + *

setState.

+ * + * @param state a int. + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutput} object. + * @throws com.pi4j.io.exception.IOException if any. + */ + default DigitalMultipurpose setState(int state) throws IOException { + return this.state(DigitalState.getState(state)); + } + /** + *

setState.

+ * + * @param state a long. + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutput} object. + * @throws com.pi4j.io.exception.IOException if any. + */ + default DigitalMultipurpose setState(long state) throws IOException { + return this.state(DigitalState.getState(state)); + } + /** + *

setState.

+ * + * @param state a float. + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutput} object. + * @throws com.pi4j.io.exception.IOException if any. + */ + default DigitalMultipurpose setState(float state) throws IOException { + return this.state(DigitalState.getState(state)); + } + /** + *

setState.

+ * + * @param state a double. + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutput} object. + * @throws com.pi4j.io.exception.IOException if any. + */ + default DigitalMultipurpose setState(double state) throws IOException { + return this.state(DigitalState.getState(state)); + } + /** + *

high.

+ * + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutput} object. + * @throws com.pi4j.io.exception.IOException if any. + */ + default DigitalMultipurpose high() throws IOException { + return this.state(DigitalState.HIGH); + } + /** + *

low.

+ * + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutput} object. + * @throws com.pi4j.io.exception.IOException if any. + */ + default DigitalMultipurpose low() throws IOException { + return this.state(DigitalState.LOW); + } + /** + *

toggle.

+ * + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutput} object. + * @throws com.pi4j.io.exception.IOException if any. + */ + default DigitalMultipurpose toggle() throws IOException { + return this.state(DigitalState.getInverseState(this.state())); + } + + /** + *

pulseHigh.

+ * + * @param interval a int. + * @param unit a {@link java.util.concurrent.TimeUnit} object. + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutput} object. + * @throws com.pi4j.io.exception.IOException if any. + */ + default DigitalMultipurpose pulseHigh(int interval, TimeUnit unit) throws IOException { + return pulse(interval, unit, DigitalState.HIGH); + } + /** + *

pulseLow.

+ * + * @param interval a int. + * @param unit a {@link java.util.concurrent.TimeUnit} object. + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutput} object. + * @throws com.pi4j.io.exception.IOException if any. + */ + default DigitalMultipurpose pulseLow(int interval, TimeUnit unit) throws IOException { + return pulse(interval, unit, DigitalState.LOW); + } + + /** + *

pulseHighAsync.

+ * + * @param interval a int. + * @param unit a {@link java.util.concurrent.TimeUnit} object. + * @param callback a {@link java.util.concurrent.Callable} object. + * @return a {@link java.util.concurrent.Future} object. + */ + default Future pulseHighAsync(int interval, TimeUnit unit, Callable callback){ + return pulseAsync(interval, unit, DigitalState.HIGH, callback); + } + + /** + *

pulseLowAsync.

+ * + * @param interval a int. + * @param unit a {@link java.util.concurrent.TimeUnit} object. + * @param callback a {@link java.util.concurrent.Callable} object. + * @return a {@link java.util.concurrent.Future} object. + */ + default Future pulseLowAsync(int interval, TimeUnit unit, Callable callback){ + return pulseAsync(interval, unit, DigitalState.LOW, callback); + } + + /** + *

pulse.

+ * + * @param interval a int. + * @param unit a {@link java.util.concurrent.TimeUnit} object. + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutput} object. + * @throws com.pi4j.io.exception.IOException if any. + */ + default DigitalMultipurpose pulse(int interval, TimeUnit unit) throws IOException { + return pulse(interval, unit, DigitalState.HIGH); + } + /** + *

pulse.

+ * + * @param interval a int. + * @param unit a {@link java.util.concurrent.TimeUnit} object. + * @param state a {@link com.pi4j.io.gpio.digital.DigitalState} object. + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutput} object. + * @throws com.pi4j.io.exception.IOException if any. + */ + default DigitalMultipurpose pulse(int interval, TimeUnit unit, DigitalState state) throws IOException { + return pulse(interval, unit, state, null); + } + + /** + *

pulseAsync.

+ * + * @param interval a int. + * @param unit a {@link java.util.concurrent.TimeUnit} object. + * @return a {@link java.util.concurrent.Future} object. + */ + default Future pulseAsync(int interval, TimeUnit unit){ + return pulseAsync(interval, unit, DigitalState.HIGH); + } + /** + *

pulseAsync.

+ * + * @param interval a int. + * @param unit a {@link java.util.concurrent.TimeUnit} object. + * @param state a {@link com.pi4j.io.gpio.digital.DigitalState} object. + * @return a {@link java.util.concurrent.Future} object. + */ + default Future pulseAsync(int interval, TimeUnit unit, DigitalState state){ + return pulseAsync(interval, unit, DigitalState.HIGH, null); + } + + /** + *

blink.

+ * + * @param interval a int. + * @param unit a {@link java.util.concurrent.TimeUnit} object. + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutput} object. + */ + default DigitalMultipurpose blink(int interval, TimeUnit unit){ + return this.blink(interval, interval, unit); + } + /** + *

blink.

+ * + * @param delay a int. + * @param duration a int. + * @param unit a {@link java.util.concurrent.TimeUnit} object. + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutput} object. + */ + default DigitalMultipurpose blink(int delay, int duration, TimeUnit unit){ + return this.blink(delay, duration, unit, DigitalState.HIGH); + } + /** + *

blink.

+ * + * @param delay a int. + * @param duration a int. + * @param unit a {@link java.util.concurrent.TimeUnit} object. + * @param state a {@link com.pi4j.io.gpio.digital.DigitalState} object. + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutput} object. + */ + default DigitalMultipurpose blink(int delay, int duration, TimeUnit unit, DigitalState state){ + return this.blink(delay, duration, unit, state, null); + } + + /** + *

blinkAsync.

+ * + * @param interval a int. + * @param unit a {@link java.util.concurrent.TimeUnit} object. + * @return a {@link java.util.concurrent.Future} object. + */ + default Future blinkAsync(int interval, TimeUnit unit){ + return this.blinkAsync(interval, interval, unit, DigitalState.HIGH); + } + /** + *

blinkAsync.

+ * + * @param delay a int. + * @param duration a int. + * @param unit a {@link java.util.concurrent.TimeUnit} object. + * @return a {@link java.util.concurrent.Future} object. + */ + default Future blinkAsync(int delay, int duration, TimeUnit unit){ + return this.blinkAsync(delay, duration, unit, DigitalState.HIGH); + } + /** + *

blinkAsync.

+ * + * @param delay a int. + * @param duration a int. + * @param unit a {@link java.util.concurrent.TimeUnit} object. + * @param state a {@link com.pi4j.io.gpio.digital.DigitalState} object. + * @return a {@link java.util.concurrent.Future} object. + */ + default Future blinkAsync(int delay, int duration, TimeUnit unit, DigitalState state){ + return this.blinkAsync(delay, duration, unit, state, null); + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMultipurposeBase.java b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMultipurposeBase.java new file mode 100644 index 00000000..005ee86a --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMultipurposeBase.java @@ -0,0 +1,212 @@ +package com.pi4j.io.gpio.digital; + +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: LIBRARY :: Java Library (CORE) + * FILENAME : DigitalMultipurposeBase.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import com.pi4j.context.Context; +import com.pi4j.exception.InitializeException; +import com.pi4j.exception.ShutdownException; +import com.pi4j.io.OnOff; +import com.pi4j.io.exception.IOException; +import com.pi4j.io.exception.IOModeException; + +import java.util.concurrent.Callable; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +/** + *

Abstract DigitalMultipurposeBase class.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public abstract class DigitalMultipurposeBase extends DigitalBase implements DigitalMultipurpose, OnOff { + + protected DigitalState state = DigitalState.UNKNOWN; + protected DigitalMode mode = DigitalMode.INPUT; + + /** + *

Constructor for DigitalMultipurposeBase.

+ * + * @param provider a {@link DigitalMultipurposeProvider} object. + * @param config a {@link DigitalMultipurposeConfig} object. + */ + public DigitalMultipurposeBase(DigitalMultipurposeProvider provider, DigitalMultipurposeConfig config){ + super(provider, config); + } + + /** {@inheritDoc} */ + @Override + public DigitalMode mode(){ + return this.mode; + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurpose mode(DigitalMode mode) throws com.pi4j.io.exception.IOException { + this.mode = mode; + return this; + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurpose initialize(Context context) throws InitializeException { + super.initialize(context); + + // set initial mode + if(config().initialMode() != null){ + try { + mode(config().initialMode()); + } catch (Exception e) { + throw new InitializeException(e); + } + } + + // update the digital state value to the initial value if an initial value was configured + if(config().initialState() != null){ + try { + DigitalMode existingMode = mode(); + if(!existingMode.isOutput()) mode(DigitalMode.OUTPUT); + state(config().initialState()); + if(!existingMode.isOutput()) mode(existingMode); + } catch (IOException e) { + throw new InitializeException(e); + } + } + + return this; + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurpose state(DigitalState state) throws IOException { + if(!this.isOutput()){ + throw new IOModeException("Unable to set state [" + state.getName() + + "] for I/O instance [" + toString() + "]; Invalid Mode: " + mode.getName()); + } + if(!this.equals(state)){ + this.state = state; + this.dispatch(new DigitalStateChangeEvent(this, this.state)); + } + return this; + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurpose pulse(int interval, TimeUnit unit, DigitalState state, Callable callback) throws IOException { + int millis = 0; + + // validate arguments + if(interval <= 0) throw new IllegalArgumentException("A time interval of zero or less is not supported."); + if(unit == TimeUnit.MICROSECONDS) throw new IllegalArgumentException("TimeUnit.MICROSECONDS is not supported."); + else if(unit == TimeUnit.DAYS) throw new IllegalArgumentException("TimeUnit.DAYS is not supported."); + else if(unit == TimeUnit.MILLISECONDS) millis = interval; + else if(unit == TimeUnit.SECONDS) millis = interval * 1000; + else if(unit == TimeUnit.MINUTES) millis = interval * 60000; + else if(unit == TimeUnit.HOURS) millis = interval * 360000; + else throw new IllegalArgumentException("TimeUnit provided is not supported."); + + // start the pulse state + this.state(state); + + // block the current thread for the pulse duration + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + throw new RuntimeException("Pulse blocking thread interrupted.", e); + } + + // end the pulse state + this.state(DigitalState.getInverseState(state)); + + // invoke callback if one was defined + if (callback != null) { + try { + callback.call(); + } catch (Exception e) { + e.printStackTrace(); + } + } + return this; + } + + /** {@inheritDoc} */ + @Override + public Future pulseAsync(int interval, TimeUnit unit, DigitalState state, Callable callback) { + // TODO :: IMPLEMENT DIGITAL OUTPUT PULSE ASYNC + throw new UnsupportedOperationException("PULSE ASYNC has not yet been implemented!"); + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurpose blink(int delay, int duration, TimeUnit unit, DigitalState state, Callable callback) { + // TODO :: IMPLEMENT DIGITAL OUTPUT BLINK + throw new UnsupportedOperationException("BLINK has not yet been implemented!"); + } + + /** {@inheritDoc} */ + @Override + public Future blinkAsync(int delay, int duration, TimeUnit unit, DigitalState state, Callable callback) { + // TODO :: IMPLEMENT DIGITAL OUTPUT BLINK ASYNC + throw new UnsupportedOperationException("BLINK ASYNC has not yet been implemented!"); + } + + /** {@inheritDoc} */ + @Override + public DigitalState state() { + return this.state; + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurpose shutdown(Context context) throws ShutdownException { + // set pin state to shutdown state if a shutdown state is configured + if(config().shutdownState() != null && config().shutdownState() != DigitalState.UNKNOWN){ + try { + state(config().shutdownState()); + } catch (IOException e) { + throw new ShutdownException(e); + } + } + return super.shutdown(context); + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurpose on() throws IOException { + // TODO :: REVISIT STATE VS ON/OFF + return high(); + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurpose off() throws IOException { + // TODO :: REVISIT STATE VS ON/OFF + return low(); + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMultipurposeConfig.java b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMultipurposeConfig.java new file mode 100644 index 00000000..6c39095e --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMultipurposeConfig.java @@ -0,0 +1,153 @@ +package com.pi4j.io.gpio.digital; + +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: LIBRARY :: Java Library (CORE) + * FILENAME : DigitalMultipurposeConfig.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + + +import com.pi4j.context.Context; + +/** + *

DigitalInputConfig interface.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public interface DigitalMultipurposeConfig extends DigitalConfig { + + /** Constant PULL_RESISTANCE_KEY="pull" */ + String PULL_RESISTANCE_KEY = DigitalInputConfig.PULL_RESISTANCE_KEY; + /** Constant DEBOUNCE_RESISTANCE_KEY="debounce" */ + String DEBOUNCE_RESISTANCE_KEY = DigitalInputConfig.DEBOUNCE_RESISTANCE_KEY; + /** Constant SHUTDOWN_STATE_KEY="shutdown" */ + String SHUTDOWN_STATE_KEY = DigitalOutputConfig.SHUTDOWN_STATE_KEY; + /** Constant INITIAL_STATE_KEY="initial" */ + String INITIAL_STATE_KEY = DigitalOutputConfig.INITIAL_STATE_KEY; + /** Constant INITIAL_MODE_KEY="mode" */ + String INITIAL_MODE_KEY = "mode"; + + /** + *

pull.

+ * + * @return a {@link PullResistance} object. + */ + PullResistance pull(); + /** + *

getPull.

+ * + * @return a {@link PullResistance} object. + */ + default PullResistance getPull(){ + return pull(); + } + + /** + *

debounce.

+ * + * @return a {@link Long} object. + */ + Long debounce(); + /** + *

getDebounce.

+ * + * @return a {@link Long} object. + */ + default Long getDebounce(){ return debounce(); } + + /** + *

shutdownState.

+ * + * @return a {@link com.pi4j.io.gpio.digital.DigitalState} object. + */ + DigitalState shutdownState(); + /** + *

shutdownState.

+ * + * @param state a {@link com.pi4j.io.gpio.digital.DigitalState} object. + * @return a {@link com.pi4j.io.gpio.digital.DigitalOutputConfig} object. + */ + DigitalMultipurposeConfig shutdownState(DigitalState state); + + /** + *

getShutdownState.

+ * + * @return a {@link com.pi4j.io.gpio.digital.DigitalState} object. + */ + default DigitalState getShutdownState(){ + return shutdownState(); + } + + /** + *

setShutdownState.

+ * + * @param state a {@link com.pi4j.io.gpio.digital.DigitalState} object. + */ + default void setShutdownState(DigitalState state){ + this.shutdownState(state); + } + + /** + *

initialState.

+ * + * @return a {@link com.pi4j.io.gpio.digital.DigitalState} object. + */ + DigitalState initialState(); + + /** + *

getInitialState.

+ * + * @return a {@link com.pi4j.io.gpio.digital.DigitalState} object. + */ + default DigitalState getInitialState(){ + return initialState(); + } + + /** + *

initialMode.

+ * + * @return a {@link com.pi4j.io.gpio.digital.DigitalMode} object. + */ + DigitalMode initialMode(); + + /** + *

getInitialMode.

+ * + * @return a {@link com.pi4j.io.gpio.digital.DigitalState} object. + */ + default DigitalMode getInitialMode(){ + return initialMode(); + } + + /** + *

newBuilder.

+ * + * @param context {@link Context} + * @return a {@link DigitalMultipurposeConfigBuilder} object. + */ + static DigitalMultipurposeConfigBuilder newBuilder(Context context) { + return DigitalMultipurposeConfigBuilder.newInstance(context); + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMultipurposeConfigBuilder.java b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMultipurposeConfigBuilder.java new file mode 100644 index 00000000..d47d0a61 --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMultipurposeConfigBuilder.java @@ -0,0 +1,99 @@ +package com.pi4j.io.gpio.digital; + +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: LIBRARY :: Java Library (CORE) + * FILENAME : DigitalMultipurposeConfigBuilder.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import com.pi4j.context.Context; +import com.pi4j.io.gpio.digital.impl.DefaultDigitalMultipurposeConfigBuilder; + +import java.util.concurrent.TimeUnit; + +/** + *

DigitalInputConfigBuilder interface.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public interface DigitalMultipurposeConfigBuilder extends DigitalConfigBuilder { + /** + *

pull.

+ * + * @param value a {@link PullResistance} object. + * @return a {@link DigitalMultipurposeConfigBuilder} object. + */ + DigitalMultipurposeConfigBuilder pull(PullResistance value); + + /** + *

debounce.

+ * + * @param microseconds a {@link Long} object. + * @return a {@link DigitalMultipurposeConfigBuilder} object. + */ + DigitalMultipurposeConfigBuilder debounce(Long microseconds); + /** + *

debounce.

+ * + * @param interval a {@link Long} object. + * @param units a {@link TimeUnit} object. + * @return a {@link DigitalMultipurposeConfigBuilder} object. + */ + DigitalMultipurposeConfigBuilder debounce(Long interval, TimeUnit units); + + /** + *

shutdown.

+ * + * @param state a {@link com.pi4j.io.gpio.digital.DigitalState} object. + * @return a {@link com.pi4j.io.gpio.digital.DigitalMultipurposeConfigBuilder} object. + */ + DigitalMultipurposeConfigBuilder shutdown(DigitalState state); + + /** + *

initial state.

+ * + * @param state a {@link com.pi4j.io.gpio.digital.DigitalState} object. + * @return a {@link com.pi4j.io.gpio.digital.DigitalMultipurposeConfigBuilder} object. + */ + DigitalMultipurposeConfigBuilder initial(DigitalState state); + + /** + *

initial mode.

+ * + * @param mode a {@link com.pi4j.io.gpio.digital.DigitalMode} object. + * @return a {@link com.pi4j.io.gpio.digital.DigitalMultipurposeConfigBuilder} object. + */ + DigitalMultipurposeConfigBuilder mode(DigitalMode mode); + + /** + *

newInstance.

+ * + * @param context {@link Context} + * @return a {@link DefaultDigitalMultipurposeConfigBuilder} object. + */ + static DigitalMultipurposeConfigBuilder newInstance(Context context) { + return DefaultDigitalMultipurposeConfigBuilder.newInstance(context); + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMultipurposeProvider.java b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMultipurposeProvider.java new file mode 100644 index 00000000..66432bcb --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMultipurposeProvider.java @@ -0,0 +1,121 @@ +package com.pi4j.io.gpio.digital; + +/* + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: LIBRARY :: Java Library (CORE) + * FILENAME : DigitalMultipurposeProvider.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +/** + *

DigitalMultipurposeProvider interface.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public interface DigitalMultipurposeProvider extends DigitalProvider { + + /** + *

create.

+ * + * @param builder a {@link DigitalMultipurposeConfigBuilder} object. + * @param a T object. + * @return a T object. + * @throws Exception if any. + */ + default T create(DigitalMultipurposeConfigBuilder builder) throws Exception { + return (T)create(builder.build()); + } + + /** + *

create.

+ * + * @param address a {@link Integer} object. + * @param a T object. + * @return a T object. + * @throws Exception if any. + */ + default T create(Integer address) throws Exception { + var config = DigitalMultipurpose.newConfigBuilder(context()) + .address(address) + .build(); + return (T)create(config); + } + + /** + *

create.

+ * + * @param address a {@link Integer} object. + * @param id a {@link String} object. + * @param a T object. + * @return a T object. + * @throws Exception if any. + */ + default T create(Integer address, String id) throws Exception { + var config = DigitalMultipurpose.newConfigBuilder(context()) + .address(address) + .id(id) + .build(); + return (T)create(config); + } + + /** + *

create.

+ * + * @param address a {@link Integer} object. + * @param id a {@link String} object. + * @param name a {@link String} object. + * @param a T object. + * @return a T object. + * @throws Exception if any. + */ + default T create(Integer address, String id, String name) throws Exception { + var config = DigitalMultipurpose.newConfigBuilder(context()) + .address(address) + .id(id) + .name(name) + .build(); + return (T)create(config); + } + + /** + *

create.

+ * + * @param address a {@link Integer} object. + * @param id a {@link String} object. + * @param name a {@link String} object. + * @param description a {@link String} object. + * @param a T object. + * @return a T object. + * @throws Exception if any. + */ + default T create(Integer address, String id, String name, String description) throws Exception { + var config = DigitalMultipurpose.newConfigBuilder(context()) + .address(address) + .id(id) + .name(name) + .description(description) + .build(); + return (T)create(config); + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMultipurposeProviderBase.java b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMultipurposeProviderBase.java new file mode 100644 index 00000000..b8ced6b6 --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalMultipurposeProviderBase.java @@ -0,0 +1,64 @@ +package com.pi4j.io.gpio.digital; + +/* + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: LIBRARY :: Java Library (CORE) + * FILENAME : DigitalMultipurposeProviderBase.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ +/** + *

Abstract DigitalMultipurposeProviderBase class.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public abstract class DigitalMultipurposeProviderBase + extends DigitalProviderBase + implements DigitalMultipurposeProvider { + + /** + *

Constructor for DigitalMultipurposeProviderBase.

+ */ + public DigitalMultipurposeProviderBase(){ + super(); + } + + /** + *

Constructor for DigitalInputProviderBase.

+ * + * @param id a {@link String} object. + */ + public DigitalMultipurposeProviderBase(String id){ + super(id); + } + + /** + *

Constructor for DigitalInputProviderBase.

+ * + * @param id a {@link String} object. + * @param name a {@link String} object. + */ + public DigitalMultipurposeProviderBase(String id, String name){ + super(id, name); + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalOutput.java b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalOutput.java index 106be55e..e5ae7137 100644 --- a/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalOutput.java +++ b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/DigitalOutput.java @@ -63,6 +63,12 @@ static DigitalOutputBuilder newBuilder(Context context){ return DigitalOutputBuilder.newInstance(context); } + /** + * Get digital mode (input|output) + * @return OUTPUT + */ + default DigitalMode mode() { return DigitalMode.OUTPUT; } + /** *

state.

* @@ -71,6 +77,7 @@ static DigitalOutputBuilder newBuilder(Context context){ * @throws IOException if any. */ DigitalOutput state(DigitalState state) throws IOException; + /** *

pulse.

* diff --git a/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/impl/DefaultDigitalMultipurposeConfig.java b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/impl/DefaultDigitalMultipurposeConfig.java new file mode 100644 index 00000000..8d194fef --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/impl/DefaultDigitalMultipurposeConfig.java @@ -0,0 +1,133 @@ +package com.pi4j.io.gpio.digital.impl; + +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: LIBRARY :: Java Library (CORE) + * FILENAME : DefaultDigitalMultipurposeConfig.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import com.pi4j.io.gpio.digital.*; +import com.pi4j.io.impl.IOAddressConfigBase; +import com.pi4j.util.StringUtil; + +import java.util.Map; + +/** + *

DefaultDigitalInputConfig class.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public class DefaultDigitalMultipurposeConfig + extends IOAddressConfigBase + implements DigitalMultipurposeConfig { + + /** + * PRIVATE CONSTRUCTOR + */ + private DefaultDigitalMultipurposeConfig(){ + super(); + } + + // private configuration properties + protected PullResistance pullResistance = PullResistance.OFF; + protected Long debounce = DigitalInput.DEFAULT_DEBOUNCE; + protected DigitalState shutdownState = null; + protected DigitalState initialState = null; + protected DigitalMode initialMode = DigitalMode.OUTPUT; + + /** + * PRIVATE CONSTRUCTOR + * + * @param properties a {@link Map} object. + */ + protected DefaultDigitalMultipurposeConfig(Map properties){ + super(properties); + + // define default property values if any are missing (based on the required address value) + this.id = StringUtil.setIfNullOrEmpty(this.id, "DIN-" + this.address, true); + this.name = StringUtil.setIfNullOrEmpty(this.name, "DIN-" + this.address, true); + this.description = StringUtil.setIfNullOrEmpty(this.description, "DIN-" + this.address, true); + + // load optional pull resistance from properties + if(properties.containsKey(PULL_RESISTANCE_KEY)){ + this.pullResistance = PullResistance.parse(properties.get(PULL_RESISTANCE_KEY)); + } + + // load optional pull resistance from properties + if(properties.containsKey(DEBOUNCE_RESISTANCE_KEY)){ + this.debounce = Long.parseLong(properties.get(DEBOUNCE_RESISTANCE_KEY)); + } + + // load initial value property + if(properties.containsKey(INITIAL_STATE_KEY)){ + this.initialState = DigitalState.parse(properties.get(INITIAL_STATE_KEY)); + } + + // load shutdown value property + if(properties.containsKey(SHUTDOWN_STATE_KEY)){ + this.shutdownState = DigitalState.parse(properties.get(SHUTDOWN_STATE_KEY)); + } + + // load initial mode property + if(properties.containsKey(INITIAL_MODE_KEY)){ + this.initialMode = DigitalMode.parse(properties.get(INITIAL_MODE_KEY)); + } + } + + /** {@inheritDoc} */ + @Override + public PullResistance pull() { + return this.pullResistance; + } + + /** {@inheritDoc} */ + @Override + public Long debounce() { return this.debounce; } + + /** {@inheritDoc} */ + @Override + public DigitalMode initialMode(){ + return this.initialMode; + } + + /** {@inheritDoc} */ + @Override + public DigitalState shutdownState(){ + return this.shutdownState; + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurposeConfig shutdownState(DigitalState state){ + this.shutdownState = state; + return this; + } + + /** {@inheritDoc} */ + @Override + public DigitalState initialState() { + return this.initialState; + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/impl/DefaultDigitalMultipurposeConfigBuilder.java b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/impl/DefaultDigitalMultipurposeConfigBuilder.java new file mode 100644 index 00000000..cb728006 --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/io/gpio/digital/impl/DefaultDigitalMultipurposeConfigBuilder.java @@ -0,0 +1,110 @@ +package com.pi4j.io.gpio.digital.impl; + +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: LIBRARY :: Java Library (CORE) + * FILENAME : DefaultDigitalMultipurposeConfigBuilder.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import com.pi4j.context.Context; +import com.pi4j.io.gpio.digital.*; + +import java.util.concurrent.TimeUnit; + +/** + *

DefaultDigitalInputConfigBuilder class.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public class DefaultDigitalMultipurposeConfigBuilder + extends DigitalConfigBuilderBase + implements DigitalMultipurposeConfigBuilder { + + /** + * PRIVATE CONSTRUCTOR + */ + protected DefaultDigitalMultipurposeConfigBuilder(Context context){ + super(context); + } + + /** + *

newInstance.

+ * + * @return a {@link DigitalInputConfigBuilder} object. + */ + public static DigitalMultipurposeConfigBuilder newInstance(Context context) { + return new DefaultDigitalMultipurposeConfigBuilder(context); + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurposeConfig build() { + DigitalMultipurposeConfig config = new DefaultDigitalMultipurposeConfig(getResolvedProperties()); + return config; + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurposeConfigBuilder pull(PullResistance value) { + this.properties.put(DigitalInputConfig.PULL_RESISTANCE_KEY, value.toString()); + return this; + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurposeConfigBuilder debounce(Long microseconds) { + if(microseconds != null) { + this.properties.put(DigitalInputConfig.DEBOUNCE_RESISTANCE_KEY, microseconds.toString()); + } + return this; + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurposeConfigBuilder shutdown(DigitalState state) { + this.properties.put(DigitalMultipurposeConfig.SHUTDOWN_STATE_KEY, state.toString()); + return this; + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurposeConfigBuilder initial(DigitalState state) { + this.properties.put(DigitalMultipurposeConfig.INITIAL_STATE_KEY, state.toString()); + return this; + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurposeConfigBuilder mode(DigitalMode mode) { + this.properties.put(DigitalMultipurposeConfig.INITIAL_MODE_KEY, mode.toString()); + return this; + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurposeConfigBuilder debounce(Long interval, TimeUnit units) { + return debounce(units.toMicros(interval)); + } +} diff --git a/pi4j-test/src/main/java/com/pi4j/test/provider/TestDigitalMultipurpose.java b/pi4j-test/src/main/java/com/pi4j/test/provider/TestDigitalMultipurpose.java new file mode 100644 index 00000000..8af901f5 --- /dev/null +++ b/pi4j-test/src/main/java/com/pi4j/test/provider/TestDigitalMultipurpose.java @@ -0,0 +1,55 @@ +package com.pi4j.test.provider; + +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: TESTING :: Unit/Integration Tests + * FILENAME : TestDigitalMultipurpose.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import com.pi4j.io.gpio.digital.*; + +/** + *

TestDigitalMultipurpose class.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public class TestDigitalMultipurpose extends DigitalMultipurposeBase implements DigitalMultipurpose { + + /** {@inheritDoc} */ + @Override + public DigitalState state() { + return this.state; + } + + /** + *

Constructor for TestDigitalInput.

+ * + * @param provider a {@link DigitalInputProvider} object. + * @param config a {@link DigitalInputConfig} object. + */ + public TestDigitalMultipurpose(DigitalMultipurposeProvider provider, DigitalMultipurposeConfig config){ + super(provider, config); + } +} diff --git a/pi4j-test/src/main/java/com/pi4j/test/provider/TestDigitalMultipurposeProvider.java b/pi4j-test/src/main/java/com/pi4j/test/provider/TestDigitalMultipurposeProvider.java new file mode 100644 index 00000000..e645090d --- /dev/null +++ b/pi4j-test/src/main/java/com/pi4j/test/provider/TestDigitalMultipurposeProvider.java @@ -0,0 +1,81 @@ +package com.pi4j.test.provider; + +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: TESTING :: Unit/Integration Tests + * FILENAME : TestDigitalMultipurposeProvider.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import com.pi4j.io.gpio.digital.DigitalMultipurpose; +import com.pi4j.io.gpio.digital.DigitalMultipurposeProvider; +import com.pi4j.test.provider.impl.TestDigitalMultipurposeProviderImpl; + +/** + *

TestDigitalInputProvider interface.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public interface TestDigitalMultipurposeProvider extends DigitalMultipurposeProvider { + /** + *

newInstance.

+ * + * @return a {@link TestDigitalMultipurposeProvider} object. + */ + static TestDigitalMultipurposeProvider newInstance(){ + return new TestDigitalMultipurposeProviderImpl(); + } + + /** + *

newInstance.

+ * + * @param id a {@link String} object. + * @return a {@link TestDigitalMultipurposeProvider} object. + */ + static TestDigitalMultipurposeProvider newInstance(String id){ + return new TestDigitalMultipurposeProviderImpl(id); + } + + /** + *

newInstance.

+ * + * @param id a {@link String} object. + * @param name a {@link String} object. + * @return a {@link TestDigitalMultipurposeProvider} object. + */ + static TestDigitalMultipurposeProvider newInstance(String id, String name){ + return new TestDigitalMultipurposeProviderImpl(id, name); + } + + /** + *

create.

+ * + * @param a T object. + * @return a T object. + * @throws Exception if any. + */ + default T create() throws Exception { + return create(0); + } +} diff --git a/pi4j-test/src/main/java/com/pi4j/test/provider/TestDigitalOutput.java b/pi4j-test/src/main/java/com/pi4j/test/provider/TestDigitalOutput.java new file mode 100644 index 00000000..f02ddfa8 --- /dev/null +++ b/pi4j-test/src/main/java/com/pi4j/test/provider/TestDigitalOutput.java @@ -0,0 +1,48 @@ +package com.pi4j.test.provider; + +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: TESTING :: Unit/Integration Tests + * FILENAME : TestDigitalOutput.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import com.pi4j.io.gpio.digital.*; + +/** + *

TestDigitalOutput class.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public class TestDigitalOutput extends DigitalOutputBase implements DigitalOutput { + /** + *

Constructor for TestDigitalInput.

+ * + * @param provider a {@link DigitalInputProvider} object. + * @param config a {@link DigitalInputConfig} object. + */ + public TestDigitalOutput(DigitalOutputProvider provider, DigitalOutputConfig config){ + super(provider, config); + } +} diff --git a/pi4j-test/src/main/java/com/pi4j/test/provider/TestDigitalOutputProvider.java b/pi4j-test/src/main/java/com/pi4j/test/provider/TestDigitalOutputProvider.java new file mode 100644 index 00000000..1f446c49 --- /dev/null +++ b/pi4j-test/src/main/java/com/pi4j/test/provider/TestDigitalOutputProvider.java @@ -0,0 +1,79 @@ +package com.pi4j.test.provider; + +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: TESTING :: Unit/Integration Tests + * FILENAME : TestDigitalOutputProvider.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import com.pi4j.io.gpio.digital.DigitalOutput; +import com.pi4j.io.gpio.digital.DigitalOutputProvider; +import com.pi4j.test.provider.impl.TestDigitalOutputProviderImpl; + +/** + *

TestDigitalInputProvider interface.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public interface TestDigitalOutputProvider extends DigitalOutputProvider { + /** + *

newInstance.

+ * + * @return a {@link TestDigitalOutputProvider} object. + */ + static TestDigitalOutputProvider newInstance(){ + return new TestDigitalOutputProviderImpl(); + } + /** + *

newInstance.

+ * + * @param id a {@link String} object. + * @return a {@link TestDigitalOutputProvider} object. + */ + static TestDigitalOutputProvider newInstance(String id){ + return new TestDigitalOutputProviderImpl(id); + } + /** + *

newInstance.

+ * + * @param id a {@link String} object. + * @param name a {@link String} object. + * @return a {@link TestDigitalOutputProvider} object. + */ + static TestDigitalOutputProvider newInstance(String id, String name){ + return new TestDigitalOutputProviderImpl(id, name); + } + + /** + *

create.

+ * + * @param a T object. + * @return a T object. + * @throws Exception if any. + */ + default T create() throws Exception { + return create(0); + } +} diff --git a/pi4j-test/src/main/java/com/pi4j/test/provider/impl/TestDigitalMultipurposeProviderImpl.java b/pi4j-test/src/main/java/com/pi4j/test/provider/impl/TestDigitalMultipurposeProviderImpl.java new file mode 100644 index 00000000..48dc2f83 --- /dev/null +++ b/pi4j-test/src/main/java/com/pi4j/test/provider/impl/TestDigitalMultipurposeProviderImpl.java @@ -0,0 +1,73 @@ +package com.pi4j.test.provider.impl; + +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: TESTING :: Unit/Integration Tests + * FILENAME : TestDigitalMultipurposeProviderImpl.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import com.pi4j.io.gpio.digital.DigitalMultipurpose; +import com.pi4j.io.gpio.digital.DigitalMultipurposeConfig; +import com.pi4j.io.gpio.digital.DigitalMultipurposeProviderBase; +import com.pi4j.test.provider.TestDigitalMultipurpose; +import com.pi4j.test.provider.TestDigitalMultipurposeProvider; + +/** + *

TestDigitalMultipurposeProviderImpl class.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public class TestDigitalMultipurposeProviderImpl extends DigitalMultipurposeProviderBase implements TestDigitalMultipurposeProvider { + + /** + *

Constructor for TestDigitalInputProviderImpl.

+ */ + public TestDigitalMultipurposeProviderImpl(){ super(); } + + /** + *

Constructor for TestDigitalInputProviderImpl.

+ * + * @param id a {@link String} object. + */ + public TestDigitalMultipurposeProviderImpl(String id){ + super(id); + } + + /** + *

Constructor for TestDigitalInputProviderImpl.

+ * + * @param id a {@link String} object. + * @param name a {@link String} object. + */ + public TestDigitalMultipurposeProviderImpl(String id, String name){ + super(id, name); + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurpose create(DigitalMultipurposeConfig config) throws Exception { + return new TestDigitalMultipurpose(this, config); + } +} diff --git a/pi4j-test/src/main/java/com/pi4j/test/provider/impl/TestDigitalOutputProviderImpl.java b/pi4j-test/src/main/java/com/pi4j/test/provider/impl/TestDigitalOutputProviderImpl.java new file mode 100644 index 00000000..f6a79a94 --- /dev/null +++ b/pi4j-test/src/main/java/com/pi4j/test/provider/impl/TestDigitalOutputProviderImpl.java @@ -0,0 +1,73 @@ +package com.pi4j.test.provider.impl; + +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: TESTING :: Unit/Integration Tests + * FILENAME : TestDigitalOutputProviderImpl.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import com.pi4j.io.gpio.digital.DigitalOutput; +import com.pi4j.io.gpio.digital.DigitalOutputConfig; +import com.pi4j.io.gpio.digital.DigitalOutputProviderBase; +import com.pi4j.test.provider.TestDigitalOutput; +import com.pi4j.test.provider.TestDigitalOutputProvider; + +/** + *

TestDigitalOutputProviderImpl class.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public class TestDigitalOutputProviderImpl extends DigitalOutputProviderBase implements TestDigitalOutputProvider { + + /** + *

Constructor for TestAnalogOutputProviderImpl.

+ */ + public TestDigitalOutputProviderImpl(){ super(); } + + /** + *

Constructor for TestAnalogOutputProviderImpl.

+ * + * @param id a {@link String} object. + */ + public TestDigitalOutputProviderImpl(String id){ + super(id); + } + + /** + *

Constructor for TestAnalogOutputProviderImpl.

+ * + * @param id a {@link String} object. + * @param name a {@link String} object. + */ + public TestDigitalOutputProviderImpl(String id, String name){ + super(id, name); + } + + /** {@inheritDoc} */ + @Override + public DigitalOutput create(DigitalOutputConfig config) throws Exception { + return new TestDigitalOutput(this, config); + } +} diff --git a/pi4j-test/src/main/java/module-info.java b/pi4j-test/src/main/java/module-info.java index 92627143..2ac1196d 100644 --- a/pi4j-test/src/main/java/module-info.java +++ b/pi4j-test/src/main/java/module-info.java @@ -45,6 +45,8 @@ uses com.pi4j.plugin.mock.provider.gpio.digital.MockDigitalInputProvider; uses com.pi4j.plugin.mock.provider.gpio.digital.MockDigitalOutput; uses com.pi4j.plugin.mock.provider.gpio.digital.MockDigitalOutputProvider; + uses com.pi4j.plugin.mock.provider.gpio.digital.MockDigitalMultipurpose; + uses com.pi4j.plugin.mock.provider.gpio.digital.MockDigitalMultipurposeProvider; uses com.pi4j.plugin.mock.provider.pwm.MockPwm; uses com.pi4j.plugin.mock.provider.pwm.MockPwmProvider; uses com.pi4j.plugin.mock.provider.i2c.MockI2C; diff --git a/pi4j-test/src/test/java/com/pi4j/test/io/gpio/digital/DigitalInputTest.java b/pi4j-test/src/test/java/com/pi4j/test/io/gpio/digital/DigitalInputTest.java new file mode 100644 index 00000000..2640f3c9 --- /dev/null +++ b/pi4j-test/src/test/java/com/pi4j/test/io/gpio/digital/DigitalInputTest.java @@ -0,0 +1,90 @@ +package com.pi4j.test.io.gpio.digital; + +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: TESTING :: Unit/Integration Tests + * FILENAME : DigitalInputTest.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import com.pi4j.Pi4J; +import com.pi4j.context.Context; +import com.pi4j.exception.Pi4JException; +import com.pi4j.io.gpio.digital.DigitalInput; +import com.pi4j.io.gpio.digital.DigitalMode; +import com.pi4j.io.gpio.digital.DigitalState; +import com.pi4j.plugin.mock.provider.gpio.digital.MockDigitalInput; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertNotNull; + +public class DigitalInputTest { + private Context pi4j; + + @Before + public void beforeTest() throws Pi4JException { + // Initialize Pi4J with auto context + // An auto context enabled AUTO-DETECT loading + // which will load any detected Pi4J extension + // libraries (Platforms and Providers) from the class path + pi4j = Pi4J.newAutoContext(); + } + + @After + public void afterTest() { + try { + pi4j.shutdown(); + } catch (Pi4JException e) { /* do nothing */ } + } + + @Test + public void testInputStates() throws Exception { + + // create I2C config + var config = DigitalInput.newConfigBuilder(pi4j) + .id("my-digital-input") + .name("My Digital Input") + .address(1) + .build(); + + // create Digital Input instance from config + MockDigitalInput digitalInput = (MockDigitalInput) pi4j.digitalInput().create(config); + + // ensure that the Digital Input instance is not null; + assertNotNull(digitalInput); + + // test MODE + Assert.assertEquals(DigitalMode.INPUT, digitalInput.mode()); + + // test HIGH state + digitalInput.mockState(DigitalState.HIGH); + Assert.assertEquals(DigitalState.HIGH, digitalInput.state()); + + // test LOW state + digitalInput.mockState(DigitalState.LOW); + Assert.assertEquals(DigitalState.LOW, digitalInput.state()); + } +} diff --git a/pi4j-test/src/test/java/com/pi4j/test/io/gpio/digital/DigitalMultipurposeTest.java b/pi4j-test/src/test/java/com/pi4j/test/io/gpio/digital/DigitalMultipurposeTest.java new file mode 100644 index 00000000..3ce89c99 --- /dev/null +++ b/pi4j-test/src/test/java/com/pi4j/test/io/gpio/digital/DigitalMultipurposeTest.java @@ -0,0 +1,161 @@ +package com.pi4j.test.io.gpio.digital; + +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: TESTING :: Unit/Integration Tests + * FILENAME : DigitalMultipurposeTest.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import com.pi4j.Pi4J; +import com.pi4j.context.Context; +import com.pi4j.exception.Pi4JException; +import com.pi4j.io.exception.IOModeException; +import com.pi4j.io.gpio.digital.DigitalMode; +import com.pi4j.io.gpio.digital.DigitalMultipurpose; +import com.pi4j.io.gpio.digital.DigitalState; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertNotNull; + +public class DigitalMultipurposeTest { + private Context pi4j; + + @Before + public void beforeTest() throws Pi4JException { + // Initialize Pi4J with auto context + // An auto context enabled AUTO-DETECT loading + // which will load any detected Pi4J extension + // libraries (Platforms and Providers) from the class path + pi4j = Pi4J.newAutoContext(); + } + + @After + public void afterTest() { + try { + pi4j.shutdown(); + } catch (Pi4JException e) { /* do nothing */ } + } + + @Test + public void testMultipurposeModes() throws Exception { + + // create Digital Multipurpose config + var config = DigitalMultipurpose.newConfigBuilder(pi4j) + .id("my-digital-multi") + .name("My Digital Multipurpose") + .address(1) + .mode(DigitalMode.INPUT) + .build(); + + // create Digital Multipurpose instance from config + var digitalMultipurpose = pi4j.digitalMultipurpose().create(config); + + // set to OUTPUT mode + digitalMultipurpose.mode(DigitalMode.OUTPUT); + Assert.assertEquals(DigitalMode.OUTPUT, digitalMultipurpose.mode()); + + // set to INPUT mode + digitalMultipurpose.mode(DigitalMode.INPUT); + Assert.assertEquals(DigitalMode.INPUT, digitalMultipurpose.mode()); + + // set to OUTPUT mode + digitalMultipurpose.output(); + Assert.assertEquals(DigitalMode.OUTPUT, digitalMultipurpose.mode()); + + // set to INPUT mode + digitalMultipurpose.input(); + Assert.assertEquals(DigitalMode.INPUT, digitalMultipurpose.mode()); + } + + @Test + public void testMultipurposeStates() throws Exception { + + // create Digital Multipurpose config + var config = DigitalMultipurpose.newConfigBuilder(pi4j) + .id("my-digital-multi") + .name("My Digital Multipurpose") + .address(1) + .mode(DigitalMode.OUTPUT) + .build(); + + // create Digital Multipurpose instance from config + var digitalMultipurpose = pi4j.digitalMultipurpose().create(config); + + // ensure that the Digital Multipurpose instance is not null; + assertNotNull(digitalMultipurpose); + + // test HIGH state + digitalMultipurpose.high(); + Assert.assertEquals(DigitalState.HIGH, digitalMultipurpose.state()); + Assert.assertEquals(DigitalMode.OUTPUT, digitalMultipurpose.mode()); + + // test LOW state + digitalMultipurpose.low(); + Assert.assertEquals(DigitalState.LOW, digitalMultipurpose.state()); + + // test HIGH state + digitalMultipurpose.setState(1); + Assert.assertEquals(DigitalState.HIGH, digitalMultipurpose.state()); + + // test LOW state + digitalMultipurpose.setState(0); + Assert.assertEquals(DigitalState.LOW, digitalMultipurpose.state()); + + // test HIGH state + digitalMultipurpose.state(DigitalState.HIGH); + Assert.assertEquals(DigitalState.HIGH, digitalMultipurpose.state()); + + // test LOW state + digitalMultipurpose.state(DigitalState.LOW); + Assert.assertEquals(DigitalState.LOW, digitalMultipurpose.state()); + } + + @Test(expected = IOModeException.class) + public void testMultipurposeInvalidMode() throws Exception { + + // create Digital Multipurpose config + var config = DigitalMultipurpose.newConfigBuilder(pi4j) + .id("my-digital-multi") + .name("My Digital Multipurpose") + .address(1) + .mode(DigitalMode.INPUT) + .build(); + + // create Digital Multipurpose instance from config + var digitalMultipurpose = pi4j.digitalMultipurpose().create(config); + + // ensure that the Digital Multipurpose instance is not null; + assertNotNull(digitalMultipurpose); + + // ensure correct MODE + Assert.assertEquals(DigitalMode.INPUT, digitalMultipurpose.mode()); + + // attempt to write HIGH state + // WE EXPECT AN 'IOModeException' BECAUSE THE MODE IS INCORRECT + digitalMultipurpose.high(); + } +} diff --git a/pi4j-test/src/test/java/com/pi4j/test/io/gpio/digital/DigitalOutputTest.java b/pi4j-test/src/test/java/com/pi4j/test/io/gpio/digital/DigitalOutputTest.java new file mode 100644 index 00000000..e576ded3 --- /dev/null +++ b/pi4j-test/src/test/java/com/pi4j/test/io/gpio/digital/DigitalOutputTest.java @@ -0,0 +1,105 @@ +package com.pi4j.test.io.gpio.digital; + +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: TESTING :: Unit/Integration Tests + * FILENAME : DigitalOutputTest.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import com.pi4j.Pi4J; +import com.pi4j.context.Context; +import com.pi4j.exception.Pi4JException; +import com.pi4j.io.gpio.digital.DigitalMode; +import com.pi4j.io.gpio.digital.DigitalOutput; +import com.pi4j.io.gpio.digital.DigitalState; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertNotNull; + +public class DigitalOutputTest { + private Context pi4j; + + @Before + public void beforeTest() throws Pi4JException { + // Initialize Pi4J with auto context + // An auto context enabled AUTO-DETECT loading + // which will load any detected Pi4J extension + // libraries (Platforms and Providers) from the class path + pi4j = Pi4J.newAutoContext(); + } + + @After + public void afterTest() { + try { + pi4j.shutdown(); + } catch (Pi4JException e) { /* do nothing */ } + } + + @Test + public void testOutputStates() throws Exception { + + // create I2C config + var config = DigitalOutput.newConfigBuilder(pi4j) + .id("my-digital-output") + .name("My Digital Output") + .address(1) + .build(); + + // create Digital Output instance from config + var digitalOutput = pi4j.digitalOutput().create(config); + + // ensure that the Digital Output instance is not null; + assertNotNull(digitalOutput); + + // test MODE + Assert.assertEquals(DigitalMode.OUTPUT, digitalOutput.mode()); + + // test HIGH state + digitalOutput.high(); + Assert.assertEquals(DigitalState.HIGH, digitalOutput.state()); + + // test LOW state + digitalOutput.low(); + Assert.assertEquals(DigitalState.LOW, digitalOutput.state()); + + // test HIGH state + digitalOutput.setState(1); + Assert.assertEquals(DigitalState.HIGH, digitalOutput.state()); + + // test LOW state + digitalOutput.setState(0); + Assert.assertEquals(DigitalState.LOW, digitalOutput.state()); + + // test HIGH state + digitalOutput.state(DigitalState.HIGH); + Assert.assertEquals(DigitalState.HIGH, digitalOutput.state()); + + // test LOW state + digitalOutput.state(DigitalState.LOW); + Assert.assertEquals(DigitalState.LOW, digitalOutput.state()); + } +} diff --git a/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/Mock.java b/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/Mock.java index 4fada79c..79cfff3d 100644 --- a/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/Mock.java +++ b/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/Mock.java @@ -71,6 +71,12 @@ public class Mock { /** Constant DIGITAL_OUTPUT_PROVIDER_ID="ID + -digital-output" */ public static final String DIGITAL_OUTPUT_PROVIDER_ID = ID + "-digital-output"; + // Digital Multipurpose (GPIO) Provider name and unique ID + /** Constant DIGITAL_MULTIPURPOSE_PROVIDER_NAME="NAME + Digital Multipurpose (GPIO) Provider" */ + public static final String DIGITAL_MULTIPURPOSE_PROVIDER_NAME = NAME + " Digital Multipurpose (GPIO) Provider"; + /** Constant DIGITAL_MULTIPURPOSE_PROVIDER_ID="ID + -digital-output" */ + public static final String DIGITAL_MULTIPURPOSE_PROVIDER_ID = ID + "-digital-multipurpose"; + // PWM Provider name and unique ID /** Constant PWM_PROVIDER_NAME="NAME + PWM Provider" */ public static final String PWM_PROVIDER_NAME = NAME + " PWM Provider"; diff --git a/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/MockPlugin.java b/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/MockPlugin.java index 34d07091..a0d42806 100644 --- a/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/MockPlugin.java +++ b/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/MockPlugin.java @@ -33,6 +33,7 @@ import com.pi4j.plugin.mock.provider.gpio.analog.MockAnalogInputProvider; import com.pi4j.plugin.mock.provider.gpio.analog.MockAnalogOutputProvider; import com.pi4j.plugin.mock.provider.gpio.digital.MockDigitalInputProvider; +import com.pi4j.plugin.mock.provider.gpio.digital.MockDigitalMultipurposeProvider; import com.pi4j.plugin.mock.provider.gpio.digital.MockDigitalOutputProvider; import com.pi4j.plugin.mock.provider.i2c.MockI2CProvider; import com.pi4j.plugin.mock.provider.pwm.MockPwmProvider; @@ -53,6 +54,7 @@ public class MockPlugin implements Plugin { MockAnalogOutputProvider.newInstance(), MockDigitalInputProvider.newInstance(), MockDigitalOutputProvider.newInstance(), + MockDigitalMultipurposeProvider.newInstance(), MockPwmProvider.newInstance(), MockI2CProvider.newInstance(), MockSpiProvider.newInstance(), diff --git a/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/provider/gpio/digital/MockDigitalMultipurpose.java b/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/provider/gpio/digital/MockDigitalMultipurpose.java new file mode 100644 index 00000000..524d297a --- /dev/null +++ b/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/provider/gpio/digital/MockDigitalMultipurpose.java @@ -0,0 +1,76 @@ +package com.pi4j.plugin.mock.provider.gpio.digital; + +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: PLUGIN :: Mock Platform & Providers + * FILENAME : MockDigitalMultipurpose.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * #L% + */ + + +import com.pi4j.io.exception.IOException; +import com.pi4j.io.gpio.digital.*; + + +/** + *

MockDigitalMultipurpose class.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public class MockDigitalMultipurpose extends DigitalMultipurposeBase implements DigitalMultipurpose { + /** + *

Constructor for MockDigitalOutput.

+ * + * @param provider a {@link DigitalOutputProvider} object. + * @param config a {@link DigitalOutputConfig} object. + */ + public MockDigitalMultipurpose(DigitalMultipurposeProvider provider, DigitalMultipurposeConfig config){ + super(provider, config); + } + + /** + *

mockState.

+ * + * @param state a {@link DigitalState} object. + * @return a {@link MockDigitalMultipurpose} object. + * @throws IOException if any. + */ + public MockDigitalMultipurpose mockState(DigitalState state) throws IOException { + this.state(state); + return this; + } + + @Override + public DigitalMultipurpose on() throws IOException { + return high(); + } + + @Override + public DigitalMultipurpose off() throws IOException { + return low(); + } + +} diff --git a/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/provider/gpio/digital/MockDigitalMultipurposeProvider.java b/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/provider/gpio/digital/MockDigitalMultipurposeProvider.java new file mode 100644 index 00000000..7a6d9afc --- /dev/null +++ b/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/provider/gpio/digital/MockDigitalMultipurposeProvider.java @@ -0,0 +1,54 @@ +package com.pi4j.plugin.mock.provider.gpio.digital; + +/* + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: PLUGIN :: Mock Platform & Providers + * FILENAME : MockDigitalMultipurposeProvider.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * #L% + */ + +import com.pi4j.io.gpio.digital.DigitalMultipurposeProvider; +import com.pi4j.plugin.mock.Mock; + +/** + *

MockDigitalOutputProvider interface.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public interface MockDigitalMultipurposeProvider extends DigitalMultipurposeProvider { + /** Constant NAME="Mock.DIGITAL_MULTIPURPOSE_PROVIDER_NAME" */ + String NAME = Mock.DIGITAL_MULTIPURPOSE_PROVIDER_NAME; + /** Constant ID="Mock.DIGITAL_MULTIPURPOSE_PROVIDER_ID" */ + String ID = Mock.DIGITAL_MULTIPURPOSE_PROVIDER_ID; + /** + *

newInstance.

+ * + * @return a {@link MockDigitalMultipurposeProvider} object. + */ + static MockDigitalMultipurposeProvider newInstance() { + return new MockDigitalMultipurposeProviderImpl(); + } +} diff --git a/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/provider/gpio/digital/MockDigitalMultipurposeProviderImpl.java b/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/provider/gpio/digital/MockDigitalMultipurposeProviderImpl.java new file mode 100644 index 00000000..c8f7abc4 --- /dev/null +++ b/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/provider/gpio/digital/MockDigitalMultipurposeProviderImpl.java @@ -0,0 +1,57 @@ +package com.pi4j.plugin.mock.provider.gpio.digital; + +/* + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: PLUGIN :: Mock Platform & Providers + * FILENAME : MockDigitalMultipurposeProviderImpl.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * #L% + */ + +import com.pi4j.io.gpio.digital.DigitalMultipurpose; +import com.pi4j.io.gpio.digital.DigitalMultipurposeConfig; +import com.pi4j.io.gpio.digital.DigitalMultipurposeProviderBase; + +/** + *

MockDigitalOutputProviderImpl class.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public class MockDigitalMultipurposeProviderImpl extends DigitalMultipurposeProviderBase implements MockDigitalMultipurposeProvider { + + /** + *

Constructor for MockDigitalOutputProviderImpl.

+ */ + public MockDigitalMultipurposeProviderImpl(){ + this.id = ID; + this.name = NAME; + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurpose create(DigitalMultipurposeConfig config) throws Exception { + return new MockDigitalMultipurpose(this, config); + } +} diff --git a/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/provider/gpio/digital/MockDigitalOutputProvider.java b/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/provider/gpio/digital/MockDigitalOutputProvider.java index 420fae4f..2db27f31 100644 --- a/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/provider/gpio/digital/MockDigitalOutputProvider.java +++ b/plugins/pi4j-plugin-mock/src/main/java/com/pi4j/plugin/mock/provider/gpio/digital/MockDigitalOutputProvider.java @@ -44,7 +44,7 @@ public interface MockDigitalOutputProvider extends DigitalOutputProvider { /** *

newInstance.

* - * @return a {@link com.pi4j.plugin.mock.provider.gpio.digital.MockDigitalOutputProvider} object. + * @return a {@link com.pi4j.plugin.mock.provider.gpio.digital.MockDigitalMultipurposeProvider} object. */ static MockDigitalOutputProvider newInstance() { return new MockDigitalOutputProviderImpl(); diff --git a/plugins/pi4j-plugin-pigpio/src/main/java/com/pi4j/plugin/pigpio/PiGpioPlugin.java b/plugins/pi4j-plugin-pigpio/src/main/java/com/pi4j/plugin/pigpio/PiGpioPlugin.java index f8a54199..9674c5c8 100644 --- a/plugins/pi4j-plugin-pigpio/src/main/java/com/pi4j/plugin/pigpio/PiGpioPlugin.java +++ b/plugins/pi4j-plugin-pigpio/src/main/java/com/pi4j/plugin/pigpio/PiGpioPlugin.java @@ -34,6 +34,7 @@ import com.pi4j.extension.PluginService; import com.pi4j.library.pigpio.PiGpio; import com.pi4j.plugin.pigpio.provider.gpio.digital.PiGpioDigitalInputProvider; +import com.pi4j.plugin.pigpio.provider.gpio.digital.PiGpioDigitalMultipurposeProvider; import com.pi4j.plugin.pigpio.provider.gpio.digital.PiGpioDigitalOutputProvider; import com.pi4j.plugin.pigpio.provider.i2c.PiGpioI2CProvider; import com.pi4j.plugin.pigpio.provider.pwm.PiGpioPwmProvider; @@ -66,6 +67,12 @@ public class PiGpioPlugin implements Plugin { /** Constant DIGITAL_OUTPUT_PROVIDER_ID="ID + -digital-output" */ public static final String DIGITAL_OUTPUT_PROVIDER_ID = ID + "-digital-output"; + // Digital Multipurpose (GPIO) Provider name and unique ID + /** Constant DIGITAL_MULTIPURPOSE_PROVIDER_NAME="NAME + Digital Output (GPIO) Provider" */ + public static final String DIGITAL_MULTIPURPOSE_PROVIDER_NAME = NAME + " Digital Multipurpose (GPIO) Provider"; + /** Constant DIGITAL_MULTIPURPOSE_PROVIDER_ID="ID + -digital-output" */ + public static final String DIGITAL_MULTIPURPOSE_PROVIDER_ID = ID + "-digital-multi"; + // PWM Provider name and unique ID /** Constant PWM_PROVIDER_NAME="NAME + PWM Provider" */ public static final String PWM_PROVIDER_NAME = NAME + " PWM Provider"; @@ -163,6 +170,7 @@ public void initialize(PluginService service) throws InitializeException { Provider providers[] = { PiGpioDigitalInputProvider.newInstance(piGpio), PiGpioDigitalOutputProvider.newInstance(piGpio), + PiGpioDigitalMultipurposeProvider.newInstance(piGpio), PiGpioPwmProvider.newInstance(piGpio), PiGpioI2CProvider.newInstance(piGpio), PiGpioSerialProvider.newInstance(piGpio), diff --git a/plugins/pi4j-plugin-pigpio/src/main/java/com/pi4j/plugin/pigpio/provider/gpio/digital/PiGpioDigitalMultipurpose.java b/plugins/pi4j-plugin-pigpio/src/main/java/com/pi4j/plugin/pigpio/provider/gpio/digital/PiGpioDigitalMultipurpose.java new file mode 100644 index 00000000..c4e155c4 --- /dev/null +++ b/plugins/pi4j-plugin-pigpio/src/main/java/com/pi4j/plugin/pigpio/provider/gpio/digital/PiGpioDigitalMultipurpose.java @@ -0,0 +1,193 @@ +package com.pi4j.plugin.pigpio.provider.gpio.digital; + +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: PLUGIN :: PIGPIO I/O Providers + * FILENAME : PiGpioDigitalMultipurpose.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * #L% + */ + + +import com.pi4j.context.Context; +import com.pi4j.exception.InitializeException; +import com.pi4j.exception.ShutdownException; +import com.pi4j.io.exception.IOModeException; +import com.pi4j.io.gpio.digital.*; +import com.pi4j.library.pigpio.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +/** + *

PiGpioDigitalMultipurpose class.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public class PiGpioDigitalMultipurpose extends DigitalMultipurposeBase implements DigitalMultipurpose { + private final PiGpio piGpio; + private final int pin; + private DigitalState state = DigitalState.LOW; + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + + /** + * Default Constructor + * + * @param piGpio a {@link PiGpio} object. + * @param provider a {@link DigitalInputProvider} object. + * @param config a {@link DigitalInputConfig} object. + * @throws IOException if any. + */ + public PiGpioDigitalMultipurpose(PiGpio piGpio, DigitalMultipurposeProvider provider, DigitalMultipurposeConfig config) throws IOException { + super(provider, config); + this.piGpio = piGpio; + this.pin = config.address().intValue(); + } + + /** + * PIGPIO Pin Change Event Handler + * + * This listener implementation will forward pin change events received from PIGPIO + * to registered Pi4J 'DigitalChangeEvent' event listeners on this digital pin. + */ + private PiGpioStateChangeListener piGpioPinListener = + event -> dispatch(new DigitalStateChangeEvent(PiGpioDigitalMultipurpose.this, DigitalState.getState(event.state().value()))); + + /** {@inheritDoc} */ + @Override + public DigitalMultipurpose initialize(Context context) throws InitializeException { + try { + // configure GPIO pin as an INPUT|OUTPUT pin + PiGpioMode pgpiomode = (mode.isOutput()) ? PiGpioMode.OUTPUT : PiGpioMode.INPUT; + this.piGpio.gpioSetMode(pin, pgpiomode); + } catch (IOException e) { + logger.error(e.getMessage(), e); + throw new InitializeException(e); + } + + super.initialize(context); + + try { + // if configured, set GPIO pin pull resistance + switch(config.pull()){ + case PULL_DOWN:{ + this.piGpio.gpioSetPullUpDown(pin, PiGpioPud.DOWN); + break; + } + case PULL_UP:{ + this.piGpio.gpioSetPullUpDown(pin, PiGpioPud.UP); + break; + } + } + + // if configured, set GPIO debounce + if(this.config.debounce() != null) { + int steadyInterval = 0; + if(this.config.debounce() > 300000){ + steadyInterval = 300000; + } else{ + steadyInterval = this.config.debounce().intValue(); + } + this.piGpio.gpioNoiseFilter(pin, 0, 0); + this.piGpio.gpioGlitchFilter(pin, steadyInterval); + } + + // add this pin listener + this.piGpio.addPinListener(pin, piGpioPinListener); + + } catch (IOException e) { + logger.error(e.getMessage(), e); + throw new InitializeException(e); + } + return this; + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurpose mode(DigitalMode mode) throws com.pi4j.io.exception.IOException { + try { + // configure GPIO pin as an INPUT|OUTPUT pin + PiGpioMode pgpiomode = (mode.isOutput()) ? PiGpioMode.OUTPUT : PiGpioMode.INPUT; + this.piGpio.gpioSetMode(pin, pgpiomode); + } catch (IOException e) { + logger.error(e.getMessage(), e); + throw new IOModeException(e.getMessage()); + } + return super.mode(mode); + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurpose state(DigitalState state) throws com.pi4j.io.exception.IOException { + // ensure the pin is in the OUPUT mode before attempting to set state + if(!this.isOutput()){ + throw new IOModeException("Unable to set state [" + state.getName() + + "] for I/O instance [" + toString() + "]; Invalid Mode: " + mode.getName()); + } + try { + this.piGpio.gpioWrite(pin, PiGpioState.from(state.value())); + } catch (IOException e) { + logger.error(e.getMessage(), e); + throw new com.pi4j.io.exception.IOException(e.getMessage(), e); + } + return super.state(state); + } + + /** {@inheritDoc} */ + @Override + public DigitalState state() { + try { + switch (this.piGpio.gpioRead(pin)) { + case LOW: { + this.state = DigitalState.LOW; + break; + } + case HIGH: { + this.state = DigitalState.HIGH; + break; + } + default: { + this.state = DigitalState.UNKNOWN; + break; + } + } + return this.state; + } + catch (Exception e){ + logger.error(e.getMessage(), e); + return DigitalState.UNKNOWN; + } + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurpose shutdown(Context context) throws ShutdownException { + // remove this pin listener + this.piGpio.removePinListener(pin, piGpioPinListener); + return super.shutdown(context); + } +} diff --git a/plugins/pi4j-plugin-pigpio/src/main/java/com/pi4j/plugin/pigpio/provider/gpio/digital/PiGpioDigitalMultipurposeProvider.java b/plugins/pi4j-plugin-pigpio/src/main/java/com/pi4j/plugin/pigpio/provider/gpio/digital/PiGpioDigitalMultipurposeProvider.java new file mode 100644 index 00000000..196cc26e --- /dev/null +++ b/plugins/pi4j-plugin-pigpio/src/main/java/com/pi4j/plugin/pigpio/provider/gpio/digital/PiGpioDigitalMultipurposeProvider.java @@ -0,0 +1,57 @@ +package com.pi4j.plugin.pigpio.provider.gpio.digital; + +/* + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: PLUGIN :: PIGPIO I/O Providers + * FILENAME : PiGpioDigitalMultipurposeProvider.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * #L% + */ + +import com.pi4j.io.gpio.digital.DigitalMultipurposeProvider; +import com.pi4j.library.pigpio.PiGpio; +import com.pi4j.plugin.pigpio.PiGpioPlugin; + +/** + *

PiGpioDigitalMultipurposeProvider interface.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public interface PiGpioDigitalMultipurposeProvider extends DigitalMultipurposeProvider { + /** Constant NAME="PiGpioPlugin.DIGITAL_MULTIPURPOSE_PROVIDER_NAME */ + String NAME = PiGpioPlugin.DIGITAL_MULTIPURPOSE_PROVIDER_NAME; + /** Constant ID="PiGpioPlugin.DIGITAL_MULTIPURPOSE_PROVIDER_ID" */ + String ID = PiGpioPlugin.DIGITAL_MULTIPURPOSE_PROVIDER_ID; + + /** + *

newInstance.

+ * + * @param piGpio a {@link PiGpio} object. + * @return a {@link PiGpioDigitalMultipurposeProvider} object. + */ + static PiGpioDigitalMultipurposeProvider newInstance(PiGpio piGpio) { + return new PiGpioDigitalMultipurposeProviderImpl(piGpio); + } +} diff --git a/plugins/pi4j-plugin-pigpio/src/main/java/com/pi4j/plugin/pigpio/provider/gpio/digital/PiGpioDigitalMultipurposeProviderImpl.java b/plugins/pi4j-plugin-pigpio/src/main/java/com/pi4j/plugin/pigpio/provider/gpio/digital/PiGpioDigitalMultipurposeProviderImpl.java new file mode 100644 index 00000000..9086ccd6 --- /dev/null +++ b/plugins/pi4j-plugin-pigpio/src/main/java/com/pi4j/plugin/pigpio/provider/gpio/digital/PiGpioDigitalMultipurposeProviderImpl.java @@ -0,0 +1,67 @@ +package com.pi4j.plugin.pigpio.provider.gpio.digital; + +/* + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: PLUGIN :: PIGPIO I/O Providers + * FILENAME : PiGpioDigitalMultipurposeProviderImpl.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * %% + * Copyright (C) 2012 - 2020 Pi4J + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * #L% + */ + +import com.pi4j.io.gpio.digital.DigitalMultipurpose; +import com.pi4j.io.gpio.digital.DigitalMultipurposeConfig; +import com.pi4j.io.gpio.digital.DigitalMultipurposeProviderBase; +import com.pi4j.library.pigpio.PiGpio; + +/** + *

PiGpioDigitalMultipurposeProviderImpl class.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public class PiGpioDigitalMultipurposeProviderImpl extends DigitalMultipurposeProviderBase implements PiGpioDigitalMultipurposeProvider { + + protected final PiGpio piGpio; + + /** + *

Constructor for PiGpioDigitalOutputProviderImpl.

+ * + * @param piGpio a {@link PiGpio} object. + */ + public PiGpioDigitalMultipurposeProviderImpl(PiGpio piGpio){ + this.id = ID; + this.name = NAME; + this.piGpio = piGpio; + } + + /** {@inheritDoc} */ + @Override + public DigitalMultipurpose create(DigitalMultipurposeConfig config) throws Exception { + // initialize the PIGPIO library + if(!piGpio.isInitialized()) piGpio.initialize(); + + // create new I/O instance based on I/O config + return new PiGpioDigitalMultipurpose(piGpio,this, config); + } +} diff --git a/pom.xml b/pom.xml index 78e28151..24b2e7cc 100644 --- a/pom.xml +++ b/pom.xml @@ -219,7 +219,6 @@ ${pi4j.default.host} 8888 - false @@ -250,7 +249,7 @@ 20020829 5.6.2 1.6.2 - 1.7.32 + 2.0.0-alpha1 2.6.2 2.8.6 20200518