Forum Replies Created

Viewing 1 post (of 1 total)
  • Author
    Posts
  • in reply to: OpenHab support and Integration Pathways for OpenSprinkler #47610

    paul8
    Participant

    For OpenSprinkler Pi, I integrated to OpenHab by writing rules directly. It wasn’t as hard as it appears, you just drive the gpio pins.

    The core of the logic was something like:

    Switch swWateringClock "Clock" <waterpump> (InternalFlags) { gpio="pin:4 force:yes activelow:yes" }
    Switch swWateringNoE "NoE" <waterpump> (InternalFlags) { gpio="pin:17 force:yes activelow:yes" }
    Switch swWateringData "Data" <waterpump> (InternalFlags) { gpio="pin:27 force:yes activelow:no" }
    Switch swWateringLatch "Latch" <waterpump> (InternalFlags) { gpio="pin:22 force:yes activelow:yes" }
    Switch swWateringUpdate "Update valves" <waterpump> (InternalFlags)

    Plus a set of switches, one for each watering line:

    Group:Number:SUM WateringSwitches "Watering Switches" (Watering)
    Switch swWatering1 "Kitchen Garden" <waterpump> (WateringSwitches)
    ...
    Switch swWatering24 "Watering 24" <waterpump> (WateringSwitches)

    And a rule that would update the OpenSprinkler Pi to turn valves on or off when something changes

    rule "Update watering status"
    when
      Item swWateringUpdate changed to ON
    then
      var int valve = 24   // number of valves on the opensprinkler pi - I have one expansion board, hence 24 valves
      
      logDebug( 'watering', 'Watering update flag is on')
      
      if( swWateringClock.state == Uninitialized || swWateringClock.state == ON ){
      	logInfo( 'watering', 'Clock was null or ON, probably means something was wrong')
      	sendCommand( swWateringClock, OFF )
      }
      
      if( swWateringNoE.state == Uninitialized ){
      	logInfo( 'watering', 'NoE was null, probably means something was wrong')
      	sendCommand( swWateringNoE, OFF )
      }
    
      if( swWateringData.state == Uninitialized || swWateringData.state == ON ){
      	logInfo( 'watering', 'Data was null or ON, probably means something was wrong')
      	sendCommand( swWateringData, OFF )
      }
    
      if( swWateringLatch.state == Uninitialized || swWateringLatch.state == ON ){
      	logInfo( 'watering', 'Latch was null or ON, probably means something was wrong')
      	sendCommand( swWateringLatch, OFF )
      }
    
      // NoE controls whether any valves are on.  Set to true if any valves are going to be on
      logDebug( 'watering', 'Total of switches is: ' + WateringSwitches.state )
      if( WateringSwitches.state > 0 && swWateringNoE.state == OFF ){
        logDebug( 'watering', 'NoE is off, turning it on' )
        sendCommand( swWateringNoE, ON )
      }
      
      if( swWateringData == null ){
      	sendCommand( swWateringData, OFF )
      }
      
      // set the Latch, which allows programming, program takes effect when turned back OFF
      sendCommand( swWateringLatch, ON )
    
      while (valve > 0) {
        // write out the value of the next valve - we write them in reverse order from 24 down to 1
        logDebug( 'watering', 'Processing valve: ' + valve )
         
        // find the next valve
        var org.openhab.core.library.items.SwitchItem currentSwitch = WateringSwitches.members.filter( m | m.name == ('swWatering' + valve ) ).last
       
        // set the data switch the same as the currentSwitch value
        logDebug( 'watering', 'Desired state is: ' + currentSwitch )
        
        if( currentSwitch.state == Uninitialized ){
          logInfo( 'watering', 'Switch was uninitialised, setting to OFF' )
          sendCommand( currentSwitch, OFF )
        }
    
        if( currentSwitch.state == OFF ){    
          sendCommand( swWateringData, OFF )
        } else {
          sendCommand( swWateringData, ON )
        }
        
        // toggle the clock to set this value before we move onto the next valve
        sendCommand( swWateringClock, ON )
        sendCommand( swWateringClock, OFF )
        valve = valve - 1
      }
    
      // turn off the Latch, makes the program take effect
      sendCommand( swWateringLatch, OFF )
    
      // NoE controls whether any valves are on.  Set to true if any valves are on
      logDebug( 'watering', 'Total of switches is: ' + WateringSwitches.state )
      if( WateringSwitches.state == 0 && swWateringNoE.state == ON ){
        logDebug( 'watering', 'NoE is on, turning it off' )
        sendCommand( swWateringNoE, OFF )
      }
      
      logDebug( 'watering', 'Turning watering update flag off')
      sendCommand( swWateringUpdate, OFF )
      
      postUpdate( dtLastWateringUpdate, new DateTimeType() )
      
      // set a timer, if nothing changes for 90 minutes, then assume someone forgot or something broke - turn everything off
      if( swWateringNoE.state == ON ) {
        logDebug( 'watering', 'Setting a timer to check that we don\'t forget to turn off')
        createTimer( now().plusMinutes( 91 ) ) [ | {
          logDebug( 'watering', 'Checking last update date to see if any changes since timer set: ' + dtLastWateringUpdate )
          
          var DateTime lastUpdate = new DateTime( ( dtLastWateringUpdate.state as DateTimeType ).calendar.timeInMillis )
          if( lastUpdate.plusMinutes( 90 ).isBefore(now) ){
            logInfo ( 'watering', 'Something ran with no changes for more than 90 minutes, turning everything off' )
            var int valveOff = 24
            while (valveOff > 0) {    
              var org.openhab.core.library.items.SwitchItem currentSwitch = WateringSwitches.members.filter( m | m.name == ('swWatering' + valveOff ) ).last
              postUpdate( currentSwitch, OFF )
              valveOff = valveOff - 1
            }
            postUpdate( swWateringUpdate, ON )
          }
        }]
      }
    end

    There’s some other bits and pieces, but that should be enough to give the idea.

Viewing 1 post (of 1 total)