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.