001package com.pi4j.jni; 002 003/* 004 * #%L 005 * ********************************************************************** 006 * ORGANIZATION : Pi4J 007 * PROJECT : Pi4J :: Java Library (Core) 008 * FILENAME : AnalogInputMonitor.java 009 * 010 * This file is part of the Pi4J project. More information about 011 * this project can be found here: https://www.pi4j.com/ 012 * ********************************************************************** 013 * %% 014 * Copyright (C) 2012 - 2021 Pi4J 015 * %% 016 * This program is free software: you can redistribute it and/or modify 017 * it under the terms of the GNU Lesser General Public License as 018 * published by the Free Software Foundation, either version 3 of the 019 * License, or (at your option) any later version. 020 * 021 * This program is distributed in the hope that it will be useful, 022 * but WITHOUT ANY WARRANTY; without even the implied warranty of 023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 024 * GNU General Lesser Public License for more details. 025 * 026 * You should have received a copy of the GNU General Lesser Public 027 * License along with this program. If not, see 028 * <http://www.gnu.org/licenses/lgpl-3.0.html>. 029 * #L% 030 */ 031 032 033import com.pi4j.util.NativeLibraryLoader; 034 035import java.util.Vector; 036 037/** 038 * <p> 039 * This class provides static methods to configure the native Pi4J library to listen to GPIO 040 * analog input value changes and invoke callbacks into this class. Additionally, this class 041 * provides a listener registration allowing Java consumers to subscribe to GPIO analog input 042 * value changes. 043 * </p> 044 * 045 * @see <a href="https://www.pi4j.com/">https://www.pi4j.com/</a> 046 * @author Robert Savage (<a 047 * href="http://www.savagehomeautomation.com">http://www.savagehomeautomation.com</a>) 048 */ 049public class AnalogInputMonitor { 050 051 private static Vector<AnalogInputListener> listeners = new Vector<>(); 052 private Object lock; 053 054 // private constructor 055 private AnalogInputMonitor() { 056 // forbid object construction 057 } 058 059 static { 060 // Load the platform library 061 NativeLibraryLoader.load("libpi4j.so", "pi4j"); 062 } 063 064 /** 065 * <p> 066 * This method is used to instruct the native code to setup a monitoring thread to monitor 067 * analog input values for changes on the selected GPIO pin. 068 * </p> 069 * 070 * @param pin GPIO pin number 071 * @param pollingRate the polling rate in milliseconds for the input monitoring thread to 072 * read analog input values from the hardware 073 * @param changeThreshold the amount of change (delta) in the analog input value required before a new 074 * analog input change event is dispatched. 075 * @return A return value of a negative number represents an error. A return value of '0' 076 * represents success and that the GPIO pin is already being monitored. A return value 077 * of '1' represents success and that a new monitoring thread was created to handle the 078 * requested GPIO pin number. 079 */ 080 public static native int enablePinValueChangeCallback(int pin, int pollingRate, double changeThreshold); 081 082 /** 083 * <p> 084 * This method is used to instruct the native code to stop the monitoring thread monitoring 085 * analog input values on the selected GPIO pin. 086 * </p> 087 * 088 * @param pin GPIO pin number 089 090 * @return A return value of a negative number represents an error. A return value of '0' 091 * represents success and that no existing monitor was previously running. A return 092 * value of '1' represents success and that an existing monitoring thread was stopped 093 * for the requested GPIO pin number. 094 */ 095 public static native int disablePinValueChangeCallback(int pin); 096 097 /** 098 * <p> 099 * This method is provided as the callback handler for the Pi4J native library to invoke when a 100 * GPIO analog input calue change is detected. This method should not be called from any Java 101 * consumers. (Thus it is marked as a private method.) 102 * </p> 103 * 104 * @param pin GPIO pin number 105 * @param value New GPIO analog input value 106 */ 107 @SuppressWarnings("unchecked") 108 private static void pinValueChangeCallback(int pin, double value) { 109 110 Vector<AnalogInputListener> listenersClone; 111 listenersClone = (Vector<AnalogInputListener>) listeners.clone(); 112 113 for (int i = 0; i < listenersClone.size(); i++) { 114 AnalogInputListener listener = listenersClone.elementAt(i); 115 if(listener != null) { 116 AnalogInputEvent event = new AnalogInputEvent(listener, pin, value); 117 listener.pinValueChange(event); 118 } 119 } 120 } 121 122 /** 123 * <p> 124 * Java consumer code can all this method to register itself as a listener for pin analog 125 * input value changes. 126 * </p> 127 * 128 * @see AnalogInputListener 129 * @see AnalogInputEvent 130 * 131 * @param listener A class instance that implements the AnalogInputListener interface. 132 */ 133 public static synchronized void addListener(AnalogInputListener listener) { 134 if (!listeners.contains(listener)) { 135 listeners.addElement(listener); 136 } 137 } 138 139 /** 140 * <p> 141 * Java consumer code can all this method to unregister itself as a listener for pin analog 142 * input value changes. 143 * </p> 144 * 145 * @see AnalogInputListener 146 * @see AnalogInputEvent 147 * 148 * @param listener A class instance that implements the AnalogInputListener interface. 149 */ 150 public static synchronized void removeListener(AnalogInputListener listener) { 151 if (listeners.contains(listener)) { 152 listeners.removeElement(listener); 153 } 154 } 155 156 157 /** 158 * <p> 159 * Returns true if the listener is already registered for event callbacks. 160 * </p> 161 * 162 * @see AnalogInputListener 163 * @see AnalogInputEvent 164 * 165 * @param listener A class instance that implements the AnalogInputListener interface. 166 */ 167 public static synchronized boolean hasListener(AnalogInputListener listener) { 168 return listeners.contains(listener); 169 } 170}