1. Sebastian Bub
  2. Raspberry Pi GPIO Web Control

Commits

Sebastian Bub  committed f09d7ae

refactored gpio init and handling to SingleContext and added cronjobs based on Quartz

  • Participants
  • Parent commits 7ac567d
  • Branches default

Comments (0)

Files changed (10)

File .hgignore

View file
  • Ignore whitespace
 logs/rpi-gpio-webapp.log*
 logs/winstone.log*
 gpio.conf
+cron.conf
 
 syntax: regexp
 \.MF$

File README.md

View file
  • Ignore whitespace
 * You can set a simulation mode for testing your client.
 * Setting multiple ports in one requests are set one after another (but the code
   is optimized that nothing unnecessary is done in between)
-
+* cronjob configuration for output ports (http://quartz-scheduler.org/documentation/quartz-2.1.x/tutorials/crontrigger)
 
 ### Planned Features
 
-* cronjob configuration for output ports (http://quartz-scheduler.org/api/2.1.0/)
 * sunset and sunrise aware cronjobs (maybe weather aware), e.g. for lights (see http://lexikon.astronomie.info/zeitgleichung/)
 * more status information via web
 
 11. Make a request, e.g. http://raspberrypi:8080/handle?g0=1&g1=0
     It will return {"g1":0,"g0":1} (and you may check the log).
 
+12. To enable cronjobs, you need to copy cron.conf.MAY_BE_CHANGED** to cron.conf and configure it
+
 
 ## Configuration and Logging and Debugging
 

File cron.conf.MAY_BE_CHANGED

View file
  • Ignore whitespace
+# Copyright 2012 der-bub.de
+# http://www.der-bub.de
+# Author: Sebastian Bub (sebastian@der-bub.de)
+#
+# 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.
+#
+#
+# see http://quartz-scheduler.org/documentation/quartz-2.1.x/tutorials/crontrigger this is crontab like (but with seconds)
+# use double colons to split between schedule and command (GET parameter syntax)
+# Fire at 10:15am every day
+# 0 15 10 ? * *         :: g0=1&g1=0
+# Fire at 10:15am every day during the year 2005
+# 0 15 10 * * ? 2005    :: g0=1
+0/20 * * ? * *             :: g0=1

File pom.xml

View file
  • Ignore whitespace
             <version>1.2.14</version>
             <type>jar</type>
         </dependency>
+        <dependency>
+            <groupId>org.quartz-scheduler</groupId>
+            <artifactId>quartz</artifactId>
+            <version>2.1.3</version>
+            <type>jar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-nop</artifactId>
+            <version>1.6.6</version>
+            <type>jar</type>
+        </dependency>
     </dependencies>
 
     <build>

File src/main/java/de/derbub/rpigpio/SingleContext.java

View file
  • Ignore whitespace
+/*
+ *
+ * Copyright 2012 der-bub.de
+ * http://www.der-bub.de
+ * Author: Sebastian Bub (sebastian@der-bub.de)
+ *
+ * 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.
+ *
+ */
+package de.derbub.rpigpio;
+
+import de.derbub.rpigpio.gpio.ConfiguredGpio;
+import de.derbub.rpigpio.gpio.Direction;
+import de.derbub.rpigpio.gpio.GpioPin;
+import de.derbub.rpigpio.gpio.GpioSysFsInterface;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import org.apache.log4j.Logger;
+
+/**
+ * Singleton class in order to have a configured context from "everywhere"
+ *
+ * @author sb
+ */
+public class SingleContext {
+
+    private static Logger log = Logger.getLogger(GpioSysFsInterface.class);
+    private static Properties configProperties = new Properties();
+    private static final String CONFIG_SIMULATE_GPIOS_KEY = "simulate.gpios";
+    private static GpioSysFsInterface gpioInterface;
+    private static SingleContext INSTANCE;
+
+    private SingleContext() {
+    }
+
+    /**
+     * Singleton creator which also initializes all GPIOs
+     *
+     * @param gpioConfigFileString
+     * @return
+     */
+    public static synchronized SingleContext getInstance(String gpioConfigFileString) {
+        if (INSTANCE == null) {
+            // read configuration file to configProperties
+            File configFile = new File(gpioConfigFileString);
+            try {
+                configProperties.load(new FileReader(configFile));
+            } catch (IOException e) {
+                if (null == gpioConfigFileString) {
+                    log.error("Configuration for gpio not found");
+                } else {
+                    if (!configFile.exists()) {
+                        log.error("Config file " + gpioConfigFileString + " does not exist");
+                    }
+                }
+                log.error(e.getClass().getName() + ":" + e.getMessage());
+            }
+            // read configuration from configProperties and initialize system
+            String simulateGpiosString = configProperties.getProperty(CONFIG_SIMULATE_GPIOS_KEY);
+            Boolean SIMULATE_GPIOS = (null == simulateGpiosString
+                    ? Boolean.TRUE
+                    : Boolean.valueOf(simulateGpiosString));
+            log.warn(CONFIG_SIMULATE_GPIOS_KEY + " is set to " + SIMULATE_GPIOS);
+
+            Map<String, ConfiguredGpio> gpioMap = new HashMap();
+            for (GpioPin gpioPin : GpioPin.values()) {
+                Direction direction = Direction.getDirectionByString(
+                        configProperties.getProperty(gpioPin.getConfigDirectionKey()));
+                String name = configProperties.getProperty(gpioPin.getConfigNameKey());
+                name = (null == name ? String.valueOf(gpioPin.getNumber()) : name);
+                if (null != direction) {
+                    ConfiguredGpio gpio = new ConfiguredGpio(gpioPin, direction, name,
+                            configProperties.getProperty(gpioPin.getConfigDefaultStateKey()),
+                            configProperties.getProperty(gpioPin.getConfigAutoToggleTimeKey()),
+                            configProperties.getProperty(gpioPin.getConfigBlockTimeKey()));
+                    ConfiguredGpio oldValue = gpioMap.put(gpio.getUserdefinedName(), gpio);
+                    log.info("Read configuration for " + gpio);
+                    if (null != oldValue) {
+                        log.warn("Conflicting gpio names: " + oldValue + " is not configured.");
+                    }
+                }
+            }
+            // setup gpio ports
+            gpioInterface = GpioSysFsInterface.getInstance(gpioMap);
+            gpioInterface.setSimulateGpios(SIMULATE_GPIOS);
+            // setup ports and default values
+            if (!gpioInterface.setupAllGpioPorts() || !gpioInterface.setAllDefaultState()) {
+                log.warn("Setup error, will cleanup immediately");
+                gpioInterface.closeAllGpioPorts();
+            }
+
+            INSTANCE = new SingleContext();
+            return INSTANCE;
+
+        }
+        throw new RuntimeException("SingleContext already initialized");
+    }
+
+    /**
+     * returns a SingleContext instance or null (if not configured yet)
+     *
+     * @return
+     */
+    public static SingleContext getInitializedInstance() {
+        return INSTANCE;
+    }
+
+    
+    /**
+     * 
+     * @param uncheckedMap
+     * @return 
+     */
+    public synchronized Map<String, String> handleGpioPorts(Map uncheckedMap) {
+        Map<String, String> nameCheckedValuesMap = checkGpioMapValidity(uncheckedMap);
+        return gpioInterface.handleGpioPorts(nameCheckedValuesMap);
+    }
+
+    
+    /**
+     * method expects userdefined names of gpio keys and values and checks keys
+     * and values
+     *
+     * @param uncheckedMap
+     * @return
+     */
+    private Map<String, String> checkGpioMapValidity(Map uncheckedMap) {
+        Map<String, ConfiguredGpio> configuredGpioMap = gpioInterface.getConfiguredGpioMap();
+        // read possible keys
+        Map<String, String> nameValuesUncheckedMap = new HashMap();
+        for (String name : configuredGpioMap.keySet()) {
+            String value = (String) uncheckedMap.get(name);
+            if (null != value) {
+                String oldValue = nameValuesUncheckedMap.put(name, value);
+                if (null != oldValue) {
+                    log.info("Conflicting values for " + name + ". " + value + " is used now");
+                }
+            }
+        }
+        // check validity of values (for keys)
+        Map<String, String> nameCheckedValuesMap = new HashMap();
+        for (String name : nameValuesUncheckedMap.keySet()) {
+            String uncheckedValue = nameValuesUncheckedMap.get(name).trim();
+            ConfiguredGpio gpio = configuredGpioMap.get(name);
+            if (gpio.getDirection().isInput()
+                    && Direction.getDirectionByString(uncheckedValue).equals(Direction.IN)) {
+                nameCheckedValuesMap.put(name, Direction.IN.getValue());
+            }
+            if (gpio.getDirection().isOutput()
+                    && ("0".equals(uncheckedValue) || "1".equals(uncheckedValue))) {
+                nameCheckedValuesMap.put(name, uncheckedValue);
+            }
+        }
+
+        return nameCheckedValuesMap;
+    }
+
+    public void destroy() {
+        INSTANCE = null;
+        gpioInterface.closeAllGpioPorts();
+    }
+}

File src/main/java/de/derbub/rpigpio/cron/CronConfigLine.java

View file
  • Ignore whitespace
+/*
+ *
+ * Copyright 2012 der-bub.de
+ * http://www.der-bub.de
+ * Author: Sebastian Bub (sebastian@der-bub.de)
+ *
+ * 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.
+ *
+ */
+package de.derbub.rpigpio.cron;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.log4j.Logger;
+
+/** Helper class which takes a crontab line, checks validity and has
+ *  some access helpers
+ *
+ * @author sb
+ */
+public class CronConfigLine {
+
+    private static Logger log = Logger.getLogger(CronConfigLine.class);
+    private String line;
+    private String schedule;
+    private String command;
+    private Map<String, String> commandMap;
+
+    public CronConfigLine(String line) {
+        this.line = line;
+        if (!line.startsWith("#")) {
+            String[] lineParts = line.split("::");
+            if (null != lineParts && lineParts.length == 2) {
+                String tmpSchedule = lineParts[0];
+                String tmpCommand = lineParts[1];
+
+                if (null != tmpSchedule && tmpSchedule.trim().length() > 0
+                        && null != tmpCommand && tmpCommand.trim().length() > 0) {
+                    schedule = tmpSchedule.trim();
+                    command = tmpCommand.trim();
+                    createCommandMap();
+                } else {
+                    log.warn("the cron line parts are ignored " + line);
+                }
+            } else {
+                log.warn("the cron line is ignored " + line);
+            }
+        }
+    }
+
+    /**
+     * checks if line looks valid (actually it has a "::" in the middle)
+     *
+     * comment is false, too
+     *
+     * @return
+     */
+    public boolean isValid() {
+        return (null != schedule && schedule.length() > 0
+                && null != command && command.length() > 0);
+    }
+
+    public String getSchedule() {
+        return schedule;
+    }
+
+    public String getCommand() {
+        return command;
+    }
+
+    public Map<String, String> getCommandMap() {
+        return commandMap;
+    }
+
+    @Override
+    public String toString() {
+        return schedule + " | " + command;
+    }
+
+    private void createCommandMap() {
+        Map<String, String> tmpMap = new HashMap<String, String>();
+        for (String param : command.split("&")) {
+            String pair[] = param.split("=");
+            String key;
+            String value = "";
+            try {
+                key = URLDecoder.decode(pair[0], "UTF-8");
+                if (pair.length > 1) {
+                    value = URLDecoder.decode(pair[1], "UTF-8");
+                }
+            } catch (UnsupportedEncodingException e) {
+                log.warn("received an UnsupportedEncodingException on key or value" + param);
+                key = pair[0];
+                value = pair[1];
+            }
+            tmpMap.put(key, value);
+        }
+        commandMap = tmpMap;
+    }
+}

File src/main/java/de/derbub/rpigpio/cron/CronjobAdapter.java

View file
  • Ignore whitespace
+/*
+ *
+ * Copyright 2012 der-bub.de
+ * http://www.der-bub.de
+ * Author: Sebastian Bub (sebastian@der-bub.de)
+ *
+ * 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.
+ *
+ */
+package de.derbub.rpigpio.cron;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.log4j.Logger;
+import static org.quartz.CronScheduleBuilder.cronSchedule;
+import org.quartz.CronTrigger;
+import static org.quartz.JobBuilder.newJob;
+import org.quartz.JobDetail;
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import static org.quartz.TriggerBuilder.newTrigger;
+import org.quartz.impl.StdSchedulerFactory;
+
+/**
+ *
+ * @author sb
+ */
+public class CronjobAdapter {
+
+    private static Logger log = Logger.getLogger(CronjobAdapter.class);
+    private Scheduler scheduler;
+    List<CronConfigLine> cronLines = new ArrayList();
+
+    public CronjobAdapter(File cronConfigFile) {
+        System.setProperty("org.terracotta.quartz.skipUpdateCheck", "true");
+
+        log.debug("reading file " + cronConfigFile);
+        BufferedReader bufferedReader = null;
+        if (cronConfigFile.exists()) {
+            try {
+                bufferedReader = new BufferedReader(new FileReader(cronConfigFile));
+                String line;
+                while ((line = bufferedReader.readLine()) != null) {
+                    CronConfigLine cronConfigLine = new CronConfigLine(line);
+                    if (cronConfigLine.isValid()) {
+                        cronLines.add(cronConfigLine);
+                    }
+                }
+            } catch (FileNotFoundException fex) {
+                log.error("file does not exists: " + cronConfigFile + "(Msg:" + fex.getMessage() + ")");
+            } catch (IOException ex) {
+                log.error("Got IOException while reading " + cronConfigFile + "(Msg:" + ex.getMessage() + ")");
+            } finally {
+                try {
+                    if (null != bufferedReader) {
+                        bufferedReader.close();
+                    }
+                } catch (Exception e) {
+                    // catch away
+                }
+            }
+        } else {
+            log.info("no cronjobs because file does not exists: " + cronConfigFile);
+        }
+    }
+
+    public void start() {
+        try {
+            if (!cronLines.isEmpty()) {
+                scheduler = StdSchedulerFactory.getDefaultScheduler();
+                scheduler.start();
+
+                Iterator iterator = cronLines.iterator();
+                while (iterator.hasNext()) {
+                    CronConfigLine ccl = (CronConfigLine) iterator.next();
+                    JobDetail job = newJob(GPIOOutJob.class).build();
+                    job.getJobDataMap().put(GPIOOutJob.COMMAND_KEY, ccl);
+                    CronTrigger trigger = newTrigger().withSchedule(cronSchedule(ccl.getSchedule())).build();
+                    scheduler.scheduleJob(job, trigger);
+                    log.info("Scheduled job: " + ccl);
+                }
+            } else {
+                log.debug("no cronjobs configured");
+            }
+        } catch (SchedulerException e) {
+            log.error("starting scheduler failed with message " + e.getMessage());
+        }
+    }
+
+    public void stop() {
+        try {
+            if (!cronLines.isEmpty()) {
+                scheduler.shutdown();
+                log.info("stopping scheduler");
+            }
+        } catch (SchedulerException e) {
+            log.error("stopping scheduler failed with message " + e.getMessage());
+        }
+    }
+}

File src/main/java/de/derbub/rpigpio/cron/GPIOOutJob.java

View file
  • Ignore whitespace
+/*
+ *
+ * Copyright 2012 der-bub.de
+ * http://www.der-bub.de
+ * Author: Sebastian Bub (sebastian@der-bub.de)
+ *
+ * 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.
+ *
+ */
+package de.derbub.rpigpio.cron;
+
+import de.derbub.rpigpio.SingleContext;
+import java.util.Date;
+import org.apache.log4j.Logger;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+
+/**
+ *
+ * @author sb
+ */
+public class GPIOOutJob implements Job {
+
+    public static final String COMMAND_KEY = "key";
+    private static Logger log = Logger.getLogger(GPIOOutJob.class);
+
+    public GPIOOutJob() {
+    }
+
+    public void execute(JobExecutionContext context) throws JobExecutionException {
+        CronConfigLine ccl = (CronConfigLine) context.getJobDetail().getJobDataMap().get(GPIOOutJob.COMMAND_KEY);
+        Date now = new Date();
+        log.info("execute() [" + now + "]: " + ccl);
+        SingleContext gpioContext = SingleContext.getInitializedInstance();
+        if (null != gpioContext) {
+            gpioContext.handleGpioPorts(ccl.getCommandMap());
+        } else {
+            log.warn("exeute() SingleContext is null");
+        }
+    }
+}

File src/main/java/de/derbub/rpigpio/web/GpioServlet.java

View file
  • Ignore whitespace
  */
 package de.derbub.rpigpio.web;
 
-import de.derbub.rpigpio.gpio.ConfiguredGpio;
-import de.derbub.rpigpio.gpio.Direction;
-import de.derbub.rpigpio.gpio.GpioPin;
-import de.derbub.rpigpio.gpio.GpioSysFsInterface;
+import de.derbub.rpigpio.SingleContext;
+import de.derbub.rpigpio.cron.CronjobAdapter;
 import java.io.File;
-import java.io.FileReader;
 import java.io.IOException;
-import java.util.HashMap;
 import java.util.Map;
-import java.util.Properties;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 public class GpioServlet extends HttpServlet {
 
     private static Logger log = Logger.getLogger(GpioServlet.class);
-    private static Properties configProperties = new Properties();
+    private static CronjobAdapter cron;
+    private static SingleContext context;
+    private static final String SYSTEM_PROPERTY_CRON_CONFIG = "cron.configuration";
     private static final String SYSTEM_PROPERTY_GPIO_CONFIG = "gpio.configuration";
-    private static final String CONFIG_SIMULATE_GPIOS_KEY = "simulate.gpios";
-    private static GpioSysFsInterface gpioInterface;
 
     /**
      * init method reads configuration and configures the gpio ports
     @Override
     public void init() {
         log.debug("init()");
-        // read configuration file to configProperties
-        String configFileString = System.getProperty(SYSTEM_PROPERTY_GPIO_CONFIG);
-        File configFile = new File(configFileString);
-        try {
-            configProperties.load(new FileReader(configFile));
-        } catch (IOException e) {
-            if (null == configFileString) {
-                log.error("System property " + SYSTEM_PROPERTY_GPIO_CONFIG + " is not set!");
-            } else {
-                if (!configFile.exists()) {
-                    log.error("Config file " + configFileString + " does not exist");
-                    log.error("It is set via system property " + SYSTEM_PROPERTY_GPIO_CONFIG + ")");
-                }
-            }
-            log.error(e.getClass().getName() + ":" + e.getMessage());
+        String gpioConfigFileString = System.getProperty(SYSTEM_PROPERTY_GPIO_CONFIG);
+        if (null == gpioConfigFileString) {
+            log.error("System property " + SYSTEM_PROPERTY_GPIO_CONFIG + " is not set!");
         }
-        // read configuration from configProperties and initialize system
-        String simulateGpiosString = configProperties.getProperty(CONFIG_SIMULATE_GPIOS_KEY);
-        Boolean SIMULATE_GPIOS = (null == simulateGpiosString
-                ? Boolean.TRUE
-                : Boolean.valueOf(simulateGpiosString));
-        log.warn(CONFIG_SIMULATE_GPIOS_KEY + " is set to " + SIMULATE_GPIOS);
+        context = SingleContext.getInstance(gpioConfigFileString);
 
-        Map<String, ConfiguredGpio> gpioMap = new HashMap();
-        for (GpioPin gpioPin : GpioPin.values()) {
-            Direction direction = Direction.getDirectionByString(
-                    configProperties.getProperty(gpioPin.getConfigDirectionKey()));
-            String name = configProperties.getProperty(gpioPin.getConfigNameKey());
-            name = (null == name ? String.valueOf(gpioPin.getNumber()) : name);
-            if (null != direction) {
-                ConfiguredGpio gpio = new ConfiguredGpio(gpioPin, direction, name,
-                        configProperties.getProperty(gpioPin.getConfigDefaultStateKey()),
-                        configProperties.getProperty(gpioPin.getConfigAutoToggleTimeKey()),
-                        configProperties.getProperty(gpioPin.getConfigBlockTimeKey()));
-                ConfiguredGpio oldValue = gpioMap.put(gpio.getUserdefinedName(), gpio);
-                log.info("Read configuration for " + gpio);
-                if (null != oldValue) {
-                    log.warn("Conflicting gpio names: " + oldValue + " is not configured.");
-                }
-            }
-        }
-        // setup gpio ports
-        gpioInterface = GpioSysFsInterface.getInstance(gpioMap);
-        gpioInterface.setSimulateGpios(SIMULATE_GPIOS);
-        // setup ports and default values
-        if (!gpioInterface.setupAllGpioPorts() || !gpioInterface.setAllDefaultState()) {
-            log.warn("Setup error, will cleanup immediately");
-            gpioInterface.closeAllGpioPorts();
-        }
+        cron = new CronjobAdapter(new File(System.getProperty(SYSTEM_PROPERTY_CRON_CONFIG)));
+        cron.start();
     }
 
     /**
     @Override
     public void destroy() {
         log.debug("destroy()");
-        gpioInterface.closeAllGpioPorts();
+        cron.stop();
+        context.destroy();
     }
 
     /**
             throws ServletException, IOException {
         log.debug("Get request for " + req.getRequestURI()
                 + "?" + req.getQueryString() + " from " + req.getRemoteAddr());
-        // read possible keys
-        Map<String, String> nameValuesUncheckedMap = new HashMap();
-        for (String name : gpioInterface.getConfiguredGpioMap().keySet()) {
-            String value = req.getParameter(name);
-            if (null != value) {
-                String oldValue = nameValuesUncheckedMap.put(name, value);
-                if (null != oldValue) {
-                    log.info("Conflicting values for " + name + ". "
-                            + value + " is used now");
-                }
-            }
-        }
-        // check validity of values (for keys)
-        Map<String, String> nameCheckedValuesMap = new HashMap();
-        for (String name : nameValuesUncheckedMap.keySet()) {
-            String uncheckedValue = nameValuesUncheckedMap.get(name).trim();
-            ConfiguredGpio gpio = gpioInterface.getConfiguredGpioMap().get(name);
-            if (gpio.getDirection().isInput()
-                    && Direction.getDirectionByString(uncheckedValue).equals(Direction.IN)) {
-                nameCheckedValuesMap.put(name, Direction.IN.getValue());
-            }
-            if (gpio.getDirection().isOutput()
-                    && ("0".equals(uncheckedValue) || "1".equals(uncheckedValue))) {
-                nameCheckedValuesMap.put(name, uncheckedValue);
-            }
-        }
+
         // set/get hardware values
-        Map<String, String> hwHandledMap =
-                gpioInterface.handleGpioPorts(nameCheckedValuesMap);
+        Map<String, String> hwHandledMap = context.handleGpioPorts(req.getParameterMap());
+
         // format response
         StringBuilder sb = new StringBuilder();
         sb.append("{");
         for (String key : hwHandledMap.keySet()) {
             sb.append((isFirst ? "" : ","));
             isFirst = false;
-            sb.append("\"").append(key).append("\":");
+            sb.append("\"").append(key.replaceAll("\"", "\\\\\"")).append("\":");
             sb.append(hwHandledMap.get(key));
         }
         sb.append("}");

File start.sh

View file
  • Ignore whitespace
 
 WARFILE=target/rpi-gpio-webapp-1.0-SNAPSHOT.war
 GPIO_CONFIG=gpio.conf
+CRON_CONFIG=cron.conf
 RPI_GPIO_LOG=file:`pwd`/log4j.properties
 
 java -Dlog4j.configuration=$RPI_GPIO_LOG \
           -Dgpio.configuration=$GPIO_CONFIG \
+          -Dcron.configuration=$CRON_CONFIG \
 		  -jar $WINSTONE_JAR \
 		  --ajp13Port=-1 \
 		  --warfile=$WARFILE \