Commits

Sebastian Bub committed 87fee5b

added more samples

Comments (0)

Files changed (3)

 ### Planned Features
 
 * Sunset and sunrise aware cronjobs, e.g. for lights (see http://lexikon.astronomie.info/zeitgleichung/)
-* More status information via web about configuration and current gpio state.
+* More status information via web about configuration.
 
 ### Possible Unplaned Features
 
 
 `GPIO.1.OUT.BLOCK.TIME=10000`
 
-The darknessSensor1in will return 1 if it is "dark" and 0 during daylight
+The darknessSensor1in will return 1 if it is "dark" and 0 during daylight.
 
 ### Manual Control
 
-In order to set it manually you could send the following request to turn on the lamp:
+In order to set the lamp manually you could send the following request to turn on the lamp: `http://raspberrypi:8080/handle?lamp1out=1`. Response would be `{"lamp1out":1}`. GPIO.1 will be set to 1 and after 250ms, it toggles back to 0. You can not control the gpio for 10 seconds.
 
-`http://raspberrypi:8080/handle?lamp1out=1`
+In order to check the sensor manually you could send the following request: `http://raspberrypi:8080/handle?darknessSensor1in=IN`. Response could be `{"darknessSensor1in":1}`. The state of the GPIO.0 is 1.
 
-GPIO.1 will be set to 1 and after 250ms, it toggles back to 0. You can not control the gpio for 10 seconds.
+In order to check the state of the lamp manually you could send the following request: `http://raspberrypi:8080/handle?lamp1out=IN`. Response could be `{"lamp1out":1}`. The lamp is on and the state of the GPIO.1 is 1.
 
-You could also send a conditional manual request (turn light on if it is dark enough):
+You could also send a conditional manual request (turn light on if it is dark enough): `http://raspberrypi:8080/handle?darknessSensor1in==1&lamp1out=1`. The answer would be `{"lamp1out":1}` if it was dark enough (and darknessSensor1in==1 is true) or `{}` if it is not dark enough (and darknessSensor1in==1 is false).
 
-`http://raspberrypi:8080/handle?darknessSensor1in==1&lamp1out=1`
+You could also check condition of another output port and react on that, e.g. `http://raspberrypi:8080/handle?otherOutputPort==0&lamp1out=1`.
 
+You have to expect the following answers: 
+
+Value | Meaning
+:---: | --------
+-2    | An output pin is blocked and can not be set now.
+-1    | A pin has no state (probably an error case).
+empty | The key and value are missing. The port is not configured or the port is configured as input and was tryed to set (or vice versa) or a conditional port was not set.
+0     | An output port was set to 0 or an input port currently returns 0.
+1     | An output port was set to 1 or an input port currently returns 1.
 
 
 ### Automatic Control
 
-Imagine you want to turn on the lamp between 16:00 and 21:00 whenever it is dark enough and turn it off at 22:30.
+Imagine you want to turn on the lamp between 16:00 and 21:00 whenever it is dark enough and turn it off at 22:30. Remember that lamp1out has a "momentary contact switch" (Therefore we have to keep track if it is turned on or off and always set port 1 to turn it on or off).
 
 Add the following lines to cron.conf:
 
 `0 * 16-21 ? * * :: VIRTUALlamp1alreadyOn==0&darknessSensor1in==1&lamp1out=1&VIRTUALlamp1alreadyOn=1`
 
-`0 30 22 ? * * :: lamp1out=0&VIRTUALlamp1alreadyOn=0`
+`0 30 22 ? * * :: VIRTUALlamp1alreadyOn==1&&lamp1out=1&VIRTUALlamp1alreadyOn=0`
 
 Every minute the virtual variable is checked VIRTUALlamp1alreadyOn. If lamp is not on, the darkness sensor darknessSensor1in is check. If both conditions are true, the lamp lamp1out is turned on and the state is changed. At 22:30, the lamp is turned off and the state is changed.
 
+You can be creative here, e.g. if you want to recheck every 15 minutes if it is still dark enough (or if there was just a dark cloud), add the follwoing line:
+
+`30 */15 16-21 ? * * :: VIRTUALlamp1alreadyOn==1&darknessSensor1in==0&lamp1out=1&VIRTUALlamp1alreadyOn=0`
+
+Just to be sure check 30 seconds later to keep you out of concurrency trouble while setting/checking VIRTUALlamp1alreadyOn.
 
 ## Copyright
 

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

 
     private static Logger log = Logger.getLogger(SingleContext.class);
     private static Properties configProperties = new Properties();
-    private static final String CONFIG_SIMULATE_GPIOS_KEY = "simulate.gpios";
-    private static final String VIRTUAL_KEY_PREFIX = "VIRTUAL";
     private static GpioSysFsInterface gpioInterface;
     private static SingleContext INSTANCE;
     private static Map<String, String> virtualVariables = new HashMap();
+    
+    public static final String CONFIG_SIMULATE_GPIOS_KEY = "simulate.gpios";
+    public static final String VIRTUAL_KEY_PREFIX = "VIRTUAL";
 
     private SingleContext() {
     }
             String uncheckedValue = nameValuesUncheckedMap.get(name).trim();
             ConfiguredGpio gpio = configuredGpioMap.get(name);
             if (gpio.getDirection().isInput()
-                    && Direction.getDirectionByString(uncheckedValue).equals(Direction.IN)) {
+                    && Direction.IN.equals(Direction.getDirectionByString(uncheckedValue))) {
                 nameCheckedValuesMap.put(name, Direction.IN.getValue());
             }
-            if (gpio.getDirection().isOutput()
-                    && ("0".equals(uncheckedValue) || "1".equals(uncheckedValue))) {
-                nameCheckedValuesMap.put(name, uncheckedValue);
+            if (gpio.getDirection().isOutput()) {
+                if (("0".equals(uncheckedValue) || "1".equals(uncheckedValue))) {
+                    nameCheckedValuesMap.put(name, uncheckedValue);
+                }
+                if (Direction.IN.equals(Direction.getDirectionByString(uncheckedValue))) {
+                    nameCheckedValuesMap.put(name, Direction.IN.getValue());
+                }
             }
         }
         return nameCheckedValuesMap;

src/main/java/de/derbub/rpigpio/gpio/GpioSysFsInterface.java

     private Boolean SIMULATE_GPIOS = Boolean.TRUE;
     private Map<String, ConfiguredGpio> configuredGpioMap = new HashMap();
     private Map<ConfiguredGpio, Long> blockedMap = new HashMap();
+    private Map<ConfiguredGpio, String> currentOutputPortState = new HashMap();
 
     protected GpioSysFsInterface() {
         /*
         return configuredGpioMap;
     }
 
+    /**
+     * method set the state if simulation should be used
+     *
+     * @param b boolean
+     */
     public void setSimulateGpios(Boolean b) {
         SIMULATE_GPIOS = b;
     }
 
-    public Boolean getSimulateGpios() {
-        return SIMULATE_GPIOS;
-    }
-
     /**
      * methods exports gpio ports and sets its direction
      *
         File aGpioFile = null;
         for (ConfiguredGpio gpio : configuredGpioMap.values()) {
             try {
+                currentOutputPortState.put(gpio, Integer.toString(gpio.getDefaultState()));
                 if (gpio.getDefaultState() == ConfiguredGpio.NO_STATE) {
                     log.debug("Set no default state for " + gpio);
                     continue;
                 String readValue = readGpio(gpio);
                 returnMap.put(name, readValue);
             } else {
-                batchedGpioOutMap.put(gpio, nameCheckedValuesMap.get(name));
+                if (Direction.IN.equals(Direction.getDirectionByString(nameCheckedValuesMap.get(name)))) {
+                    returnMap.put(name, currentOutputPortState.get(gpio));
+                } else {
+                    batchedGpioOutMap.put(gpio, nameCheckedValuesMap.get(name));
+                }
             }
         }
         if (!batchedGpioOutMap.isEmpty()) {
         ConfiguredGpio[] perfileConfiguredGpioArray = new ConfiguredGpio[perfFileWriterArray.length];
         int perfIndex = 0;
         Long nowForBlocking = System.currentTimeMillis();
-        
+
         // for each gpio prepare (if blocked and add to perfArrays)
         for (ConfiguredGpio gpio : outGpioValueMap.keySet()) {
             String value = outGpioValueMap.get(gpio);
             if (SIMULATE_GPIOS) {
                 log.warn("Simulate set state " + value + (isAutoTogglingThread ? " (autoToggle)" : "") + " for " + gpio);
                 returnMap.put(gpio.getUserdefinedName(), value);
+                currentOutputPortState.put(gpio, value);
                 if (!isAutoTogglingThread && gpio.getAutoToogleTime() != ConfiguredGpio.NO_DEFAULT_TIME) {
                     autoToggleList.add(gpio);
                 }
             long before = System.currentTimeMillis();
             for (i = 0; i < perfIndex; i++) {
                 FileWriter aGpioFileWriter = perfFileWriterArray[i];
-                if(null != aGpioFileWriter){
-                aGpioFileWriter.write(perfValueArray[i]);
-                aGpioFileWriter.flush();                    
+                if (null != aGpioFileWriter) {
+                    aGpioFileWriter.write(perfValueArray[i]);
+                    aGpioFileWriter.flush();
                 } else {
                     log.debug("File handle for file " + aGpioFile + " is null, ignoring.");
                 }
             }
             long after = System.currentTimeMillis();
-            log.info("Writing of gpio ports took " + (after-before) + "ms at " + after  + (SIMULATE_GPIOS?" (in simulation)":""));
-      } catch (Exception e) {
+            log.info("Writing of gpio ports took " + (after - before) + "ms at " + after + (SIMULATE_GPIOS ? " (in simulation)" : ""));
+        } catch (Exception e) {
             // if we get here, forget about timing: log and overwrite
             log.error("Got " + e.getClass().getName() + " with message: " + e.getMessage() + " with file " + aGpioFile);
             returnMap.put(perfileConfiguredGpioArray[i].getUserdefinedName(), Integer.toString(ConfiguredGpio.NO_STATE));
                 try {
                     if (null != aGpioFileWriter) {
                         aGpioFileWriter.close();
+                        currentOutputPortState.put(perfileConfiguredGpioArray[i], perfValueArray[i]);
                     }
                 } catch (Exception e) {
                     log.error("Got a " + e.getClass().getName() + " with message: " + e.getMessage() + " with file " + aGpioFile
         }
         // if we have something to toggle back to default state later, do it
         if (!isAutoTogglingThread && !autoToggleList.isEmpty()) {
-            GpioOutAutoToggleThread atThread = new GpioOutAutoToggleThread(autoToggleList, (System.currentTimeMillis()-nowForBlocking));
+            GpioOutAutoToggleThread atThread = new GpioOutAutoToggleThread(autoToggleList, (System.currentTimeMillis() - nowForBlocking));
             atThread.start();
         }
         return returnMap;
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.