Für dieses Beispiel ist ein auf dem Raspberry Pi installierter Glassfish erforderlich, sowie pi4j als auch jquery.
Einfache Website mit Tabelle und Buttons zum de- und aktivieren
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang="de"> <head> <title>GPIO Webinterface</title> <!-- Stylesheet einbinden --> <link href="style.css" rel="stylesheet" type="text/css"/> <!-- JQuery Bibliothek einbinden --> <script src="code.jquery.com_jquery-1.10.2.js" type="text/javascript"></script> </head> <body> <div id="content"> <!-- Tabelle anlegen --> <table id="table" class="center"> <tr> <!-- eine Zeile der Tabelle --> <td>button</td> <!--button für on anlegen --> <td><input id="button_on" type="button" value="on"/></td> <!--button für off anlegen --> <td><input id="button_off" type="button" value="off"/></td> <!--icon anlegen --> <td><span class="icon" id="button_icon">●</span></td> </tr> </table> <!-- Javascript muss am Ende eingebunden werden --> <script src="script.js" type="text/javascript"></script> </div> </body> </html>
//ajax Cache deaktivieren $.ajaxSetup({cache: false}); //Funktion Update starten $(function () { update(); //Update funktion rekursiv function update() { //read Methode aufrufen read(); //update nach 3000ms erneut aufrufen //so wird die Darstellung bei externen Veränderungen //automatisch angepasst setTimeout(update, 3000); } }); //reaktion auf Button mit der id button_on $("#button_on").click(function () { //html get request $.get("co/button/on", function (data) { $(".result").html(data); //read Methode aufrufen read(); }); }); //reaktion auf Button mit der id button_off $("#button_off").click(function () { //html get request $.get("co/button/off", function (data) { $(".result").html(data); //read Methode aufrufen read(); }); }); function read() { //inhalt von get request abfragen $.get("co/button", function (data) { //Ergebnis des requests in var data schreiben $(".result").html(data); //abfrage ob data = false oder true if (data == "false") { //Farben der Buttons und des Icons über css verändern $("#button_icon").css("color", "#ff0000"); $("#button_on").css("color", "#000000"); $("#button_off").css("color", "#0000ff"); } else if (data == "true") { //Farben der Buttons und des Icons über css verändern $("#button_icon").css("color", "#00ff66"); $("#button_on").css("color", "#0000ff"); $("#button_off").css("color", "#000000"); } }); }
body{ /*Seitenhintergrund ändern*/ background: #333333; } table.center{ /*Tabelle mit klasse center zentrieren*/ margin-left: auto; margin-right: auto; } #table{ /*Tabelle über Seitenbreite*/ width: 100%; /*Hintergrundfarbe weiß*/ background: #ffffff; /*Standardschriftgröße*/ font-size: 30px; /*Schriftgröße abhängig von der Auflösung*/ font-size: 3.5vw; } #table td{ /*Rahmenstärke*/ border: 1px solid; /*Text mittig*/ text-align: center; } #table td input { /*Buttonbreite*/ width: 25%; /*Standardschriftgröße*/ font-size: 25px; /*Schriftgröße Abhängig von der Auflösung*/ font-size:3.5vw; }
Die Java Implementierung läuft über eine REST-Schnittstelle und die pi4j Bibliothek
import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; import java.util.Arrays; import java.util.HashSet; import java.util.Set; //Rest Service anmelden @ApplicationPath("/co") public class ApplicationConfig extends Application { @Override public Set<Class<?>> getClasses() { return new HashSet<Class<?>>(Arrays.asList(Button.class, Utilities.class)); } }
import com.pi4j.io.gpio.GpioPinDigitalOutput; import com.pi4j.io.gpio.PinPullResistance; import com.pi4j.io.gpio.PinState; import gpio.GPIOManager; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ejb.Singleton; import javax.ws.rs.PathParam; @Singleton //Über Rest nur eine Instanz anmelden @Path("/button") public class Button{ //In dieser Klasse wird auf die Implementierung GPIOManager zugegriffen //siehe weiter unten public static final int id = 1; private GpioPinDigitalOutput pin; //Returned bei Aufruf von website/co/button den Wert true oder false @GET public String isOn() { return String.valueOf(GPIOManager.getInstance().isPinHigh(id)); } //Setzt durch GET Aufruf den Pin auf on oder off @GET @Path("{on}") public void setOn(@PathParam("on") String on) { pin = GPIOManager.getInstance().getPinByID(id); if (pin != null) { if ("on".equals(on)) { pin.high(); pin.setShutdownOptions(true, PinState.HIGH, PinPullResistance.OFF); } else if ("off".equals(on)) { pin.low(); pin.setShutdownOptions(true, PinState.LOW, PinPullResistance.OFF); } } } }
import gpio.GPIOManager; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ejb.Singleton; @Singleton @Path("/shutdown") public class Utilities { //Bei Aufruf von shutdown wird diese Info zurückgegeben @GET public String help() { return "use /shutdown/r for reboot or /shutdown/h for halt"; } @GET //Über GET Aufruf das Linux System neustarten @Path("/r") public void reboot() { try { GPIOManager.getInstance().Shutdown(); Runtime runtime = Runtime.getRuntime(); runtime.exec("shutdown -r now"); } catch (IOException ex) { Logger.getLogger(Utilities.class.getName()).log(Level.SEVERE, null, ex); } } //Über GET Aufruf das Linux System herunterfahren @GET @Path("/h") public void halt() { try { GPIOManager.getInstance().Shutdown(); Runtime runtime = Runtime.getRuntime(); runtime.exec("shutdown -h now"); } catch (IOException ex) { Logger.getLogger(Utilities.class.getName()).log(Level.SEVERE, null, ex); } } }
import com.pi4j.io.gpio.GpioController; import com.pi4j.io.gpio.GpioFactory; import com.pi4j.io.gpio.GpioPin; import com.pi4j.io.gpio.GpioPinDigitalOutput; import com.pi4j.io.gpio.PinState; import com.pi4j.io.gpio.RaspiPin; import java.util.Collection; public final class GPIOManager { private final GpioController gpio = GpioFactory.getInstance(); private GpioPinDigitalOutput pin1; private static GPIOManager instance = null; protected GPIOManager() { } //Singleton Pattern zum einmaligen erzeugen der Klasse public static GPIOManager getInstance() { if (instance == null) { synchronized (GPIOManager.class) { if (instance == null) { instance = new GPIOManager(); } } } return instance; } //Liefert die GPIOFactory der pi4j Bibliothek public GpioController getGpioControllerInstance() { return gpio; } //Singleton Pattern zum erzeugen der Pins und festlegen einer ID für jeden Pin //Vorbereitung für mehrere Pins public GpioPinDigitalOutput getPinByID(int id) { if (id == 1) { //Einmaliges erzeugen des Pins if (pin1 == null) { Collection<GpioPin> provisionedPins = getGpioControllerInstance().getProvisionedPins(); for (GpioPin provisionedPin : provisionedPins) { //Prüfen ob der Pin schon registriert wurde if ("Button".equals(provisionedPin.getName())){ return (GpioPinDigitalOutput) provisionedPin; } } //Pin neu erzeugen pin1 = getGpioControllerInstance().provisionDigitalOutputPin(RaspiPin.GPIO_01, "Button", PinState.LOW); } return pin1; } return null; } //Liefert den aktuellen Status eines Pins public boolean isPinHigh(int id){ GpioPinDigitalOutput pinByID = getPinByID(id); return pinByID.getState().isHigh() ; } //Pins freigeben und Pin Controller herunterfahren public void Shutdown() { getGpioControllerInstance().shutdown(); pin1 = null; } }