OpenSprinkler Forums Third-Party Software OpenHab support and Integration Pathways for OpenSprinkler 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.

We are currently away till Monday July 21. Orders placed during this time will be shipped on Tuesday July 22. Thank you for your understanding!
This is default text for notification bar