AT Smart House

I thought I’d document some stuff here on my openHAB setup, to get some tips or suggestions from the community.

My name is Aaron. I live in Australian. I’m really interested in IoT in the last year or so and home automation, and slowly automating and smartifying my existing house as I go.

Setup
So I’m running openHAB on a Raspberry Pi 3. I used the Openhabian installer, and it was a fairly straight forward installation from my friend MK Smart House. Thanks I friend.

General
I actually started out my beginner journey with MK-Smart House video.
My MK Sprinkler was my first real step into an actual smart home, and I had lots of fun playing around, the wireless switch with useing the App on my phone is good,

Matt from MK-Smart House show how to manually program rules.

Next I got 3 Yeelight Lights (just useing one right now as there are Screwing bulbs)

I have and fronius solar inverter what I have a Bridge in “things” to get info from

I have the Open Weather Map Binding but am looking to move to Bom (what is a Australian weather website.

I also have 1 google home, 1 google mini, 1 google Chromecast working with OpenHab

Broadlink work with MQTT to turn on and off my Projector and HiFI.

Stuff that isn’t working right

So there is a few stuff I’m trying that isn’t working correctly yet, and I’m working on it. =P

*Need to make some “Rules” to not water when rain is coming.

*I have a old tablet, which I have not got HABPanel on or anything of openhab on it yet, wait to have the right tools that I like

*I have InfluxDB and Grafana, get some dater from my solar but have been able to moved the graph to openhab yet.

*I like to make an graph that counts how long I water my plants and convert into liters.

*Looking to Monitor how much power I using and selling back to the power grid

*I got 2 Digoo BB-M1X Ip camera’s yet to be put into Openhab yet to be don have been told have to use this software IspyConnect thanks to BK Hobby.

*I also have 2 wemos thinking of making something like this with taking temperature also.


I like to show my Items and sitemaps and Rules and my influxdb.persist file (I just started with grafana)
So if I have stuff some thing up I like to know.

home.Items

//This is the Items File 

//Sprinkler System
Switch MKSprinklerSystemZone1       "Mock Orange Hedges"                    <rain>                  [ "Switchable" ] {mqtt=">[broker:MKSmartHouse/utilities/MkSprinklerSystem:command:ON:Z1ON],>[broker:MKSmartHouse/utilities/MkSprinklerSystem:command:OFF:Z1OFF],<[broker:MKSmartHouse/utilities/MkSprinklerSystem/state:state:ON:Z1ON],<[broker:MKSmartHouse/utilities/MkSprinklerSystem/state:state:OFF:Z1OFF]", autoupdate="false"}
Switch MKSprinklerSystemZone2       "Greenhouse"                            <rain>                  [ "Switchable" ] {mqtt=">[broker:MKSmartHouse/utilities/MkSprinklerSystem:command:ON:Z2ON],>[broker:MKSmartHouse/utilities/MkSprinklerSystem:command:OFF:Z2OFF],<[broker:MKSmartHouse/utilities/MkSprinklerSystem/state:State:ON:Z2ON],<[broker:MKSmartHouse/utilities/MkSprinklerSystem/state:State:OFF:Z2OFF]", autoupdate="false"}
Switch MKSprinklerSystemZone3       "Herb Garden"                           <rain>                  [ "Switchable" ] {mqtt=">[broker:MKSmartHouse/utilities/MkSprinklerSystem:command:ON:Z3ON],>[broker:MKSmartHouse/utilities/MkSprinklerSystem:command:OFF:Z3OFF],<[broker:MKSmartHouse/utilities/MkSprinklerSystem/state:state:ON:Z3ON],<[broker:MKSmartHouse/utilities/MkSprinklerSystem/state:State:OFF:Z3OFF]", autoupdate="false"}
Switch SprinklerCycle               "1 Minute Cycle"                        <rain>
Switch SprinklerSystemSchedule      "Sprinkler System Schedule"             <calendar>

//YEELIGHT
Group gLivingRomeYeeLight           "Light"                                 <lightbulb>     (gLivingRomeYeeLight)

Color  CouchLEDColor                "Living Room Light"                     <colorpicker>   (gLivingRomeYeeLight)       [ "Lighting" ]
Dimmer CouchLEDColorTemp            "Living Color Temp"                     <light>         (gLivingRomeYeeLight)       [ "Switchable" ]

//Fronius
Group gsolarPanels                  "Solar"                                 <SUN>           (gsolarPanels)

Number AC_Powery                    "AC POWER"                              <SUN>           (gsolarPanels)                              { channel="fronius:powerinverter:mybridge:myinverter:inverterdatachannelpac" }
Number Day_Energy                   "DAY ENERGY"                            <SUN>           (gsolarPanels)                              { channel="fronius:powerinverter:mybridge:myinverter:inverterdatachanneldayenergy" }
Number Total_Energy                 "TOTAL ENERGY"                          <SUN>           (gsolarPanels)                              { channel="fronius:powerinverter:mybridge:myinverter:inverterdatachanneltotal" }
Number Year_Energy                  "YERA ENERGY"                           <SUN>           (gsolarPanels)                              { channel="fronius:powerinverter:mybridge:myinverter:inverterdatachannelyear" }

//MK-Room Chromecast
Group gChromecast                   "Chromecast"                            <screen>        (gChromecast)

Dimmer LivingRoomChromecastVolume    "Living Room Chromecast Volume"        <soundvolume>   (gChromecast)              [ "Switchable" ] { channel="chromecast:chromecast:9b4caa68fea98442d4a9a75c66f5263c:volume" }
Player LivingRoomChromecastControl   "Living Room Chromecast Control"       <mediacontrol>  (gChromecast)                               { channel="chromecast:chromecast:9b4caa68fea98442d4a9a75c66f5263c:control" }

//Broadlink
Group gLiveingRoomBroadlink          "TV Remote"                            <mediacontrol> (gLiveingRoomBroadlink)

Switch Projector                       "Projector"                          <projector>     (gLiveingRoomBroadlink)    [ "Switchable" ]  {mqtt=">[broker:broadlink/epson_projector/on:command:ON:play],>[broker:broadlink/epson_projector/off:command:OFF:play"}
Switch Hifi                            "HiFi"                               <receiver>      (gLiveingRoomBroadlink)    [ "Switchable" ]  {mqtt=">[broker:broadlink/sonyhifi/on-off:command:ON:play],>[broker:broadlink/sonyhifi/on-off:command:OFF:play"}

//Open westher Map
DateTime	            owmCurrentStationTimestamp          "Time UpDate [%1$tA, %1$td.%1$tm.%1$tY %1$tH:%1$tM]"	<time>		               {channel="openweathermap:weather:api:local:current#time-stamp"}
String					owmCurrentCondition			        "Condition [%s]"					                    <sun_clouds>	           {channel="openweathermap:weather:api:local:current#condition"}
Number:Temperature		owmCurrentTemperature		        "Temperatur [%.1f %unit%]"			                    <temperature>	           {channel="openweathermap:weather:api:local:current#temperature"}
Number:Dimensionless    owmCurrentHumidity			        "Humidity [%.1f %unit%]"	                            <humidity>                 {channel="openweathermap:weather:api:local:current#humidity"}
Number:Speed			owmCurrentWindSpeed			        "Wind Speed [%.1f km/h]"	                            <wind>                     {channel="openweathermap:weather:api:local:current#wind-speed"}
Number:Dimensionless	owmCurrentWindDirection             "Wind Direction [SCALE(wind.scale):%s]"	                <wind>                     {channel="openweathermap:weather:api:local:current#wind-direction"}
Number:Dimensionless	owmCurrentCloudiness		        "Cloudiness [%.1f %unit%]"			                    <sun_clouds>	           {channel="openweathermap:weather:api:local:current#cloudiness"}
Number:Length			owmCurrentRain				        "Rain [%.1f %unit%]"				                    <rain>                     {channel="openweathermap:weather:api:local:current#rain"}

home.Rules

//This is the Rules File
 
//If sprinkler system schedule is on then water each zone at 5 am for 20 min
rule "Sprinkler System Schedule"
when
  Time cron "0 0 5 1/1 * ? *"
then
  if(SprinklerSystemSchedule.state == ON)
  {
      sendBroadcastNotification("SPRINKLER SYSTEM: Daily Watering Active")
      sendCommand(MKSprinklerSystemZone1, ON)
      createTimer(now.plusMinutes(0)) [|
           sendCommand( MKSprinklerSystemZone1, OFF)
           sendCommand( MKSprinklerSystemZone2, ON)
           createTimer(now.plusMinutes(2)) [|
               sendCommand( MKSprinklerSystemZone2, OFF)
               sendCommand( MKSprinklerSystemZone3, ON)
               createTimer(now.plusMinutes(2)) [|
                   sendCommand( MKSprinklerSystemZone3, OFF)
               ]
          ]
      ]
  }
end

//If 20 Minute Cycle Switch Is On then water each zone for 20 min
rule "1 Minute Cycle"
when
  Item SprinklerCycle received update ON
then
      sendBroadcastNotification("SPRINKLER SYSTEM: 1 Minute Cycle Active")
      sendCommand(MKSprinklerSystemZone1, ON)
      createTimer(now.plusMinutes(1)) [|
           sendCommand( MKSprinklerSystemZone1, OFF)
           sendCommand( MKSprinklerSystemZone2, ON)
           createTimer(now.plusMinutes(1)) [|
               sendCommand( MKSprinklerSystemZone2, OFF)
               sendCommand( MKSprinklerSystemZone3, ON)
               createTimer(now.plusMinutes(1)) [|
                   sendCommand( MKSprinklerSystemZone3, OFF)
               ]
          ]
      ]
      sendCommand(SprinklerCycle, OFF)
end

home.Sitmaps

sitemap home label="AT-SmartHouse"
{
    Frame label="Information"{
        Text item=owmCurrentTemperature label="Weather [%.1f %unit%]" {
            Text item=owmCurrentStationTimestamp
            Text item=owmCurrentCondition
            Text item=owmCurrentTemperature
            Text item=owmCurrentHumidity
            Text item=owmCurrentRain
            Text item=owmCurrentCloudiness
            Text item=owmCurrentWindDirection
            Text item=owmCurrentWindSpeed
            }
     Group item=gsolarPanels
     }
 Frame label="Living Room"{
     Group item=gLiveingRoomBroadlink
     Group item=gChromecast
     Group item=gLivingRomeYeeLight
     }
 Frame label="Outside"{
     Text label="Sprinkler" icon=garden{
         Switch item=MKSprinklerSystemZone1
         Switch item=MKSprinklerSystemZone2
         Switch item=MKSprinklerSystemZone3
         Switch item=SprinklerCycle
         Switch item=SprinklerSystemSchedule  
         }
     }

}

influxdb.persist

Strategies 
{
    everyMinute : "0 * * * * ?"
    everyHour   : "0 0 * * * ?"
    everyDay    : "0 0 0 * * ?"
}

Items 
{
    owmCurrentTemperature   : strategy = everyChange
    owmCurrentHumidity      : strategy = everyChange
    AC_Powery               : strategy = everyChange
    owmCurrentRain          : strategy = everyUpdate
    MKSprinklerSystemZone1  : strategy = everyChange
    MKSprinklerSystemZone2  : strategy = everyChange
    MKSprinklerSystemZone3  : strategy = everyChange
    owmCurrentCloudiness    : strategy = everyChange
    
}

I have to say thanks guys for helping me this far :smiley:
and look forward for any comments or help or corrections.

2 Likes

For the sprinkler see Design Pattern: Cascading Timers for an alternative way to implement it. The key features your current approach lacks are the ability to cancel the irrigation and handling the case where OH goes offline while the irrigation is running.

I’ll also note that in your first rule, zone 1 will turn on then off almost instantly because of the plusMinutes(0), then zone 2 will run for 2 minutes, then zone 3 will run for 2 minutes. This is not the behavior described in the comment.

The only real difference between the two rules is the trigger, why not combining them? One of your major goals should always be too avoid duplicating code.

For the minor differences between the two rules you can test to see if receivedCommand is null. If it is null you know the rule was triggered by the time trigger. If it isn’t null you know it was triggered by received command.

1 Like

Hey Aaron,

Welcome

Im in the same boat as you, I have my sprinklers hooked up, (got info from mk smart house), i then altered code and built my own to make it easier.

I also have most lights using sonoff basic devices running tasmota.

I have my xiaomi vacuum on OH too.

I also have my Garage Door running off a relay, My alarm system running off a wemos D1mini, transistors and a 433mhz remote.

I haven’t figured out if i can get my goodwe solar inverter integrated yet.

Can I ask, how did you integrate the chromecast and what do you do with it?

Re the not water when rain is coming, You could use a weather binding and alter the rules if rain is predicted in the next day or so. You could also use soil moisture sensors and only water when the moisture is low (this is what im trying to do right now).

Home.items file

// This is the items file

Group mapDB
Group:Switch:OR(ON,OFF) OutdoorLighting "Outdoor Lights [%s]" <light>
Group:Switch:OR(ON,OFF) IndoorLighting "Indoor Lights [%s]"  <light>  (mapDB) 
Group:Switch:OR(ON,OFF) gIrrigation "Irrigation [%s]" <faucet> 
Group gIrrigationTimes (mapDB)
Group GNeato
Group Alarm 
Group:Switch:OR(ON,OFF) gPresence
Group:Dimmer:AVG blinds "Blinds are [SCALE(blinds.scale):%s]" (mapDB)
Group Garage (mapDB)

//*********************************
//Lighting
//***********


Switch FrontDownlights 		"Front Downlights"	<light> (OutdoorLighting) [ "Switchable" ] 	{ mqtt="<[broker:stat/FrontDownlightsSonoff/POWER:state:default],>[broker:cmnd/FrontDownlightsSonoff/power:command:*:default]" }
Number FrontDownlight_RSSI 	"Front Downlight: RSSI [%d %%]"  					{ mqtt="<[broker:tele/FrontDownlightsSonoff/STATE:state:JSONPATH($.Wifi.RSSI)]" }
String FrontDownlight_IP 	"Get Info"  										{ mqtt=">[broker:cmnd/FrontDownlightsSonoff/IPAddress1:command:*:*]" }
String FrontDownlight_IP_String "Info [%s]"	 									{ mqtt="<[broker:stat/FrontDownlightsSonoff/RESULT:state:default]" }
String FrontDownlightStateString	"Info"										{ mqtt="<[broker:tele/FrontDownlightsSonoff/STATE:state:default]" } //hidden string to be updated depending on status 


Switch BackyardLights 		"Backyard lights"	<light> (OutdoorLighting)   [ "Switchable" ]	{ mqtt="<[broker:stat/BackyardLights/POWER:state:default],>[broker:cmnd/BackyardLights/power:command:*:default]" }
Number BackyardLights_RSSI 	"Backyard lights: RSSI [%d %%]"  								{ mqtt="<[broker:tele/BackyardLights/STATE:state:JSONPATH($.Wifi.RSSI)]" }
String BackyardLights_IP 	"Get Info"  													{ mqtt=">[broker:cmnd/BackyardLights/IPAddress1:command:*:*]" }
String BackyardLights_IP_String "Info [%s]"	 												{ mqtt="<[broker:stat/BackyardLights/RESULT:state:default]" }
String BackyardLightsStateString	"Info"													{ mqtt="<[broker:tele/BackyardLights/STATE :state:default]" } //hidden string to be updated depending on status 

Switch GarageLights 		"Garage lights"	<light>   (IndoorLighting)  [ "Switchable" ]   { mqtt="<[broker:stat/GarageLights/POWER:state:default],>[broker:cmnd/GarageLights/power:command:*:default]" }
Number GarageLights_RSSI 	"Garage lights: RSSI [%d %%]"  								{ mqtt="<[broker:tele/GarageLights/STATE:state:JSONPATH($.Wifi.RSSI)]" }
String GarageLights_IP 	"Get Info"  													{ mqtt=">[broker:cmnd/GarageLights/IPAddress1:command:*:*]" }
String GarageLights_IP_String "Info [%s]"	 											{ mqtt="<[broker:stat/GarageLights/RESULT:state:default]" }
String GarageLightsStateString	"Info"													{ mqtt="<[broker:tele/GarageLights/STATE :state:default]" } //hidden string to be updated depending on status 

Switch LoungeLight 		"Lounge room Light"	<light> (IndoorLighting)           [ "Switchable" ]   { mqtt="<[broker:stat/LoungeLight/POWER:state:default],>[broker:cmnd/LoungeLight/power:command:*:default]" }
Number LoungeLight_RSSI 	"Lounge room Light: RSSI [%d %%]"  								{ mqtt="<[broker:tele/LoungeLight/STATE:state:JSONPATH($.Wifi.RSSI)]" }
String LoungeLight_IP 	"Get Info"  													{ mqtt=">[broker:cmnd/LoungeLight/IPAddress1:command:*:*]" }
String LoungeLight_IP_String "Info [%s]"	 												{ mqtt="<[broker:stat/LoungeLight/RESULT:state:default]" }
String LoungeLightStateString	"Info"													{ mqtt="<[broker:tele/LoungeLight/STATE :state:default]" } //hidden string to be updated depending on status 

//*********************************
//Blinds
//***********
Number MainBedBlindsSettings															{ mqtt=">[broker:MainBedBlinds/1:command:*:default]" }		
Dimmer MainBedBlinds1 	"Master Bedroom First Window [%d]"  	<none>	(blinds)		[ "Switchable" ] 	{ mqtt="<[broker:MainBedBlinds/Location/1:state:default],>[broker:MainBedBlinds/1:command:*:default]" }
Dimmer MainBedBlinds2 	"Master Bedroom Second Window [%d]"  	<none>	(blinds)		[ "Switchable" ] 	{ mqtt="<[broker:MainBedBlinds/Location/2:state:default],>[broker:MainBedBlinds/2:command:*:default]" }
Dimmer MainBedBlinds3 	"Master Bedroom Third Window [%d]"  	<none>	(blinds)		[ "Switchable" ] 	{ mqtt="<[broker:MainBedBlinds/Location/3:state:default],>[broker:MainBedBlinds/3:command:*:default]" }
Dimmer AllMainBlinds "Master Bedroom Blinds"						[ "Switchable" ] 


String MainBlindStatus	{ mqtt="<[broker:MainBedBlinds/status/get:state:default]" } //hidden string to be updated depending on status
DateTime BedBlindsOnline "Last Online at [%1$tl:%1$tM%1$tp on %1$tA, %1$tB %1$te, %1$tY]"  (mapDB)
															


Number LoungeBlindsSettings																{ mqtt=">[broker:LoungeBlinds/1:command:*:default]" }		
Dimmer LoungeBlinds1 	"Lounge First Window [%d]"  			<none>	(blinds)		[ "Switchable" ]	{ mqtt="<[broker:LoungeBlinds/Location/1:state:default],>[broker:LoungeBlinds/1:command:*:default]" }
Dimmer LoungeBlinds2	"Lounge Second Window [%d]"  			<none>	(blinds)		[ "Switchable" ]	{ mqtt="<[broker:LoungeBlinds/Location/2:state:default],>[broker:LoungeBlinds/2:command:*:default]" }
Dimmer LoungeBlinds3 	"Lounge Third Window [%d]"  			<none>	(blinds)		[ "Switchable" ]	{ mqtt="<[broker:LoungeBlinds/Location/3:state:default],>[broker:LoungeBlinds/3:command:*:default]" }
Dimmer AllLoungeBlinds "All Lounge Blinds"							[ "Switchable" ]


String LoungeBlindsStatus	{ mqtt="<[broker:LoungeBlinds/status/get:state:default]" } //hidden string to be updated depending on status
DateTime LoungeBlindsLastOnline "Last Online at [%1$tl:%1$tM%1$tp on %1$tA, %1$tB %1$te, %1$tY]" (mapDB)


Dimmer AllBlinds "All Blinds"				[ "Switchable" ]	


//*********************************
//Sprinkler System
//***********


String Irrigation_Zone1  	(gIrrigationTimes)
String Irrigation_Zone2 	(gIrrigationTimes)
String Irrigation_Zone3 	(gIrrigationTimes)
String Irrigation_Zone4 	(gIrrigationTimes)


Switch SprinklerSystemZone1 "Front Grass Sprinklers"     	(gIrrigation)      	[ "Switchable" ] 	{ mqtt=">[broker:SprinklerSystem:command:ON:Z1ON],>[broker:SprinklerSystem:command:OFF:Z1OFF]" }
Switch SprinklerSystemZone2 "Front Garden Sprinklers" 	   	(gIrrigation)	 		[ "Switchable" ] 	{ mqtt=">[broker:SprinklerSystem:command:ON:Z2ON],>[broker:SprinklerSystem:command:OFF:Z2OFF]" }
Switch SprinklerSystemZone3 "Back Grass Sprinklers" 		(gIrrigation)			[ "Switchable" ] 	{ mqtt=">[broker:SprinklerSystem:command:ON:Z3ON],>[broker:SprinklerSystem:command:OFF:Z3OFF]" }
Switch SprinklerSystemZone4 "Back Garden Sprinklers" 		(gIrrigation)		[ "Switchable" ] 	{ mqtt=">[broker:SprinklerSystem:command:ON:Z4ON],>[broker:SprinklerSystem:command:OFF:Z4OFF]" }


Number Countdown_Zone1 		"Minutes Remaining [%d]"	(gIrrigationTimes)
Number Countdown_Zone2 		"Minutes Remaining [%d]"	(gIrrigationTimes)
Number Countdown_Zone3		"Minutes Remaining [%d]"	(gIrrigationTimes)
Number Countdown_Zone4 		"Minutes Remaining [%d]"    (gIrrigationTimes)
                         
Switch SprinklerSystemSchedule1 "Front Grass Schedule"  	(gIrrigationTimes)
Switch SprinklerSystemSchedule2 "Front Garden Schedule" 	(gIrrigationTimes)		
Switch SprinklerSystemSchedule3 "Back Grass Schedule" 		(gIrrigationTimes)	
Switch SprinklerSystemSchedule4 "Back Garden Schedule"  	(gIrrigationTimes)

DateTime Irrigation_StartTime1  "Zone 1 Last Watered [%1$ta %1$tR]"  (gIrrigationTimes)
DateTime Irrigation_StartTime2  "Zone 2 Last Watered [%1$ta %1$tR]"  (gIrrigationTimes)
DateTime Irrigation_StartTime3  "Zone 3 Last Watered [%1$ta %1$tR]"  (gIrrigationTimes)
DateTime Irrigation_StartTime4  "Zone 4 Last Watered [%1$ta %1$tR]"  (gIrrigationTimes)


Number onHours1 "Front Grass Sprinkler Minutes" 	(gIrrigationTimes)
Number onHours2 "Front Garden Sprinkler Minutes"	(gIrrigationTimes)
Number onHours3 "Back Grass Sprinkler Minutes"		(gIrrigationTimes)
Number onHours4 "Back Garden Sprinkler Minutes"		(gIrrigationTimes)

String IFTTString "If this then that string" (All)


DateTime Sunset_Time        "Sunset [%1$tH:%1$tM]"                    { channel="astro:sun:local:set#start" }

//*********************************
//alarm
//***********


String AlarmKeypad
Switch Unlocked
String KeypadString
Switch ARM "Arm"  		(Alarm)  [ "Switchable" ]
Switch DISARM "Disarm"  (Alarm)  [ "Switchable" ]
Switch STAY "Stay"      (Alarm)  [ "Switchable" ]

String AlarmString 		"Alarm"	<alarm> (Alarm)      [ "Switchable" ]   
String Alarm															{ mqtt=">[broker:AlarmSystem:command:*:Default]" }

//*********************************
//Garage Door
//***********

Switch GarageDoorSwitch		"Garage Door"									[ "Switchable" ] 				{ mqtt=">[broker:cmnd/GarageDoorSonoff/POWER:command:*:default]" }
Rollershutter GarageDoor		 
String GarageDoorState 			          	
Switch GarageDoorClosed										(Garage)					{ mqtt="<[broker:cmnd/GarageDoorSensors/POWER1:state:default]" }
Switch GarageDoorOpened										(Garage)					{ mqtt="<[broker:cmnd/GarageDoorSensors/POWER2:state:default]" }
Number Garage_RSSI 	"Garage: RSSI [%d %%]"  									{ mqtt="<[broker:tele/GarageDoorSonoff/STATE:state:JSONPATH($.Wifi.RSSI)]" }
String Garage_IP 	"Get Info"  												{ mqtt=">[broker:cmnd/GarageDoorSonoff/IPAddress1:command:*:*]" }
String Garage_IP_String "Info [%s]"	 											{ mqtt="<[broker:stat/GarageDoorSonoff/RESULT:state:default]" }
Switch GarageDoorAuto "Garage Door auto close 9PM-5AM" 		(Garage)
Switch GarageDoorStateUpdate 													{ mqtt=">[broker:cmnd/GarageDoorSonoff/STATUS:command:*:10]" } //hidden button to get update of garage door status. Runs every minute
String GarageDoorStateString													{ mqtt="<[broker:tele/GarageDoorSonoff/SENSOR:state:default]" } //hidden string to be updated depending on status 

//*********************************
//Neato Robot
//***********

//String ETName  "Name [%s]" 
//Number ETBattery  "Battery level [%.0f %%]" <battery>   							{channel="neato:vacuumcleaner:OPS13617-38D2697EFCE2:battery-level"}
//String ETState  "Status [MAP(neato-sv.map):%s]" <chart>							{channel="neato:vacuumcleaner:OPS13617-38D2697EFCE2:state"}
//String ETError  "Error [%s]"  													{channel="neato:vacuumcleaner:OPS13617-38D2697EFCE2:error"}
//String ETVersion  "Version [%s]" <none> (GNeato) 									{channel="neato:vacuumcleaner:OPS13617-38D2697EFCE2:version"}
//String ETModel  "Model [%s]" <none>(GNeato) 										{channel="neato:vacuumcleaner:OPS13617-38D2697EFCE2:model-name"}
//String ETFirmware  "Firmware [%s]" <none>(GNeato) 								{channel="neato:vacuumcleaner:OPS13617-38D2697EFCE2:firmware"}
//String ETAction  "Action [%s]" <chart>											{channel="neato:vacuumcleaner:OPS13617-38D2697EFCE2:action"}	
//Switch ETDockHasBeenSeen  "Seen dock [%s]" <present> (GNeato) 					{channel="neato:vacuumcleaner:OPS13617-38D2697EFCE2:dock-has-been-seen"}
//Switch ETIsDocked  "In dock [MAP(neato-sv.map):%s]" <present> 					{channel="neato:vacuumcleaner:OPS13617-38D2697EFCE2:is-docked"}
//Switch ETIsScheduled  "Scheduled [%s]" <calendar>(GNeato) 						{channel="neato:vacuumcleaner:OPS13617-38D2697EFCE2:is-scheduled"}
//Switch ETIsCharging  "Is Charging [%s]" <battery> (GNeato) 						{channel="neato:vacuumcleaner:OPS13617-38D2697EFCE2:is-charging"}
//String ETCategory  "Cleaning Category [MAP(neato-sv.map):%s]" <none> (GNeato) 	{channel="neato:vacuumcleaner:OPS13617-38D2697EFCE2:cleaning-category"}
//String ETMode  "Cleaning Mode [MAP(neato-sv.map):%s]" <none> (GNeato) 			{channel="neato:vacuumcleaner:OPS13617-38D2697EFCE2:cleaning-mode"}
//String ETModifier  "Cleaning Modifier [MAP(neato-sv.map):%s]" <none> (GNeato) 	{channel="neato:vacuumcleaner:OPS13617-38D2697EFCE2:cleaning-modifier"}
//Number ETSpotWidth  "SpotWidth [%.0f]" <none> (GNeato) 							{channel="neato:vacuumcleaner:OPS13617-38D2697EFCE2:cleaning-spotwidth"}
//Number ETSpotHeight  "SpotHeight [%.0f]" <none>(GNeato) 							{channel="neato:vacuumcleaner:OPS13617-38D2697EFCE2:cleaning-spotheight"}
//String ETCommand																	{channel="neato:vacuumcleaner:OPS13617-38D2697EFCE2:command"}
//String ETCommandSitemap


//*********************************
//Sonof Reboot Items
//***********

String	Sonoff_Action "All Sonoff Devices" <sonoff_basic>

//*********************************
//Network Devices online
//***********
Switch ChrisPhone 					(gPresence)											{channel="network:pingdevice:192_168_0_149:online"}
Switch AimeePhone					(gPresence)											{channel="network:pingdevice:192_168_0_187:online"}
//Switch LoungeBlindsPresence					(gPresence)											{channel="network:pingdevice:192_168_0_163:online"}

Number FrontGrassMoisture									(gIrrigationTimes)								{ mqtt="<[broker:FrontGrassSensor/Stat:state:default]" }	
DateTime FrontGrassMoistureTime        "Last Updated [%1$ta %1$tR]"        	(gIrrigationTimes)            
					
//************************************

mapdb.persist

Strategies {
	default = everyChange
}
Items {
	mapDB : strategy = everyChange, restoreOnStartup
  mapDB*: strategy = everyChange, restoreOnStartup
}

home.rules
Might help you a little with your irrigation


var Timer timer1
var Timer timer2
var Timer timer3
var Timer timer4


//This is the rules page


rule "Reset Irrigation at OH Start"
when
    System started
then

createTimer(now.plusSeconds(20)) [|
LoungeBlindsSettings.sendCommand(LoungeBlinds1.state as Number + 200)
LoungeBlindsSettings.sendCommand(LoungeBlinds2.state as Number + 400)
LoungeBlindsSettings.sendCommand(LoungeBlinds3.state as Number + 600)
MainBedBlindsSettings.sendCommand(MainBedBlinds1.state as Number + 200)
MainBedBlindsSettings.sendCommand(MainBedBlinds2.state as Number + 400)
MainBedBlindsSettings.sendCommand(MainBedBlinds3.state as Number + 600)
]

end




//**************************************************************************************
rule "Zone 1 Inactive"
when
    Item SprinklerSystemZone1 received command OFF

then
Countdown_Zone1.postUpdate(0)
Irrigation_Zone1.postUpdate("Inactive")
if (timer1 !== null)
	{
	timer1.cancel
	timer1 = null
	}
end
//**************************************************************************************
rule "Zone 2 Inactive"
when
    Item SprinklerSystemZone2 received command OFF

then
Countdown_Zone2.postUpdate(0)
Irrigation_Zone2.postUpdate("Inactive")
if (timer2 !== null)
	{
	timer2.cancel
	timer2 = null
	}
end
//**************************************************************************************
rule "Zone 3 Inactive"
when
    Item SprinklerSystemZone3 received command OFF

then
Countdown_Zone3.postUpdate(0)
Irrigation_Zone3.postUpdate("Inactive")
if (timer3 !== null)
	{
	timer3.cancel
	timer3 = null
	}

end
//**************************************************************************************
rule "Zone 4 Inactive"
when
    Item SprinklerSystemZone4 received command OFF

then
Countdown_Zone4.postUpdate(0)
Irrigation_Zone4.postUpdate("Inactive")
if (timer4 !== null)
	{
	timer4.cancel
	timer4 = null
	}
end

//**************************************************************************************
//Zone 1 Watering	


rule "Zone 1 Watering"
when
    Item SprinklerSystemZone1 changed to ON
then

if (onHours1.state !== NULL)
	{
	
	
		var Number timeout = onHours1.state as DecimalType
		var int lawnTime = (timeout).intValue
		postUpdate(Irrigation_StartTime1, new DateTimeType())
		Irrigation_Zone1.postUpdate("Active")

		if (lawnTime > 0)
		{
		sendBroadcastNotification("Watering Zone 1 for " +  timeout.toString + " minutes")
		Irrigation_Zone1.postUpdate("Active " + timeout.toString + " minutes remaining")
		Countdown_Zone1.postUpdate(lawnTime)

		}
	}
else
	{
	SprinklerSystemZone1.sendCommand(OFF)
	onHours1.postUpdate(30)
	sendBroadcastNotification("Zone 1 does not have a timer set, this zone has been set to 30 minutes, please try again")

	}
end

//**************************************************************************************
//Zone 2 Watering


rule "Zone 2 Watering"
when
    Item SprinklerSystemZone2 changed to ON
then

if (onHours2.state !== NULL)
	{
	
		var Number timeout = onHours2.state as DecimalType
		var int lawnTime = (timeout).intValue
		postUpdate(Irrigation_StartTime2, new DateTimeType())
		Irrigation_Zone2.postUpdate("Active")
		if (lawnTime > 0)
		{
		sendBroadcastNotification("Watering Zone 2 for " +  timeout.toString + " minutes")
		Irrigation_Zone2.postUpdate("Active " + timeout.toString + " minutes remaining")
		Countdown_Zone2.postUpdate(lawnTime)

		}
	}
else
	{
	SprinklerSystemZone2.sendCommand(OFF)
	onHours2.postUpdate(30)
	sendBroadcastNotification("Zone 2 does not have a timer set, this zone has been set to 30 minutes, please try again")

	}
end

//**************************************************************************************
//Zone 3 Watering


rule "Zone 3 Watering"
when
    Item SprinklerSystemZone3 changed to ON
then

if (onHours3.state !== NULL)
	{
		var Number timeout = onHours3.state as DecimalType
		var int lawnTime = (timeout).intValue
				postUpdate(Irrigation_StartTime3, new DateTimeType())
		Irrigation_Zone3.postUpdate("Active")
		if (lawnTime > 0)
		{
		sendBroadcastNotification("Watering Zone 3 for " +  timeout.toString + " minutes")
		Countdown_Zone3.postUpdate(lawnTime)

		}
	}	
else
	{
	SprinklerSystemZone3.sendCommand(OFF)
	onHours3.postUpdate(30)
	sendBroadcastNotification("Zone 3 does not have a timer set, this zone has been set to 30 minutes, please try again")

	}
end

//**************************************************************************************
//Zone 4 Watering


rule "Zone 4 Watering"
when
    Item SprinklerSystemZone4 changed to ON
then

if (onHours4.state !== NULL)
	{
	var Number timeout = onHours4.state as DecimalType
	var int lawnTime = (timeout).intValue
        postUpdate(Irrigation_StartTime4, new DateTimeType())
	Irrigation_Zone4.postUpdate("Active")
		if (lawnTime > 0)
		{
		sendBroadcastNotification("Watering Zone 4 for " +  timeout.toString + " minutes")
		Irrigation_Zone4.postUpdate("Active " + timeout.toString + " minutes remaining")
		Countdown_Zone4.postUpdate(lawnTime)
		}
	}
	else
	{
	SprinklerSystemZone4.sendCommand(OFF)
	onHours4.postUpdate(30)
	sendBroadcastNotification("Zone 4 does not have a timer set, this zone has been set to 30 minutes, please try again")
	}
end

//***************************************************************************

rule "Countdown Zone 1 Timer"
when
        Item Countdown_Zone1 received update
then	
if (Countdown_Zone1.state as DecimalType >= 1 && SprinklerSystemZone1.state == ON)
		{
			Irrigation_Zone1.postUpdate("Active " + (Countdown_Zone1.state as DecimalType) + " minutes remaining")
	    	timer1 = createTimer(now.plusMinutes(1)) [|
			Countdown_Zone1.postUpdate(Countdown_Zone1.state as DecimalType - 1)
			]
		}
			
if (Countdown_Zone1.state as DecimalType == 0 && SprinklerSystemZone1.state == ON)
				{
				SprinklerSystemZone1.sendCommand(OFF)
				sendBroadcastNotification("Finished Watering Zone 1")
				}
end
//***************************************************************************
rule "Countdown Zone 2 Timer"
when
        Item Countdown_Zone2 received update
then	
if (Countdown_Zone2.state as DecimalType >= 1 && SprinklerSystemZone2.state == ON)
		{
			Irrigation_Zone2.postUpdate("Active " + (Countdown_Zone2.state as DecimalType) + " minutes remaining")
	    	timer2 = createTimer(now.plusMinutes(1)) [|
			Countdown_Zone2.postUpdate(Countdown_Zone2.state as DecimalType - 1)
			]
		}
			
if (Countdown_Zone2.state as DecimalType == 0 && SprinklerSystemZone2.state == ON)
				{
				SprinklerSystemZone2.sendCommand(OFF)
				sendBroadcastNotification("Finished Watering Zone 2")
				}
end
//***************************************************************************

rule "Countdown Zone 3 Timer"
when
        Item Countdown_Zone3 received update
then	
if (Countdown_Zone3.state as DecimalType >= 1 && SprinklerSystemZone3.state == ON)
		{
			Irrigation_Zone3.postUpdate("Active " + (Countdown_Zone3.state as DecimalType) + " minutes remaining")
	    	timer3 = createTimer(now.plusMinutes(1)) [|
			Countdown_Zone3.postUpdate(Countdown_Zone3.state as DecimalType - 1)
			]
		}
			
if (Countdown_Zone3.state as DecimalType == 0 && SprinklerSystemZone3.state == ON)
				{
				SprinklerSystemZone3.sendCommand(OFF)
				sendBroadcastNotification("Finished Watering Zone 3")
				}
end
//***************************************************************************

rule "Countdown Zone 4 Timer"
when
        Item Countdown_Zone4 received update
then	
if (Countdown_Zone4.state as DecimalType >= 1 && SprinklerSystemZone4.state == ON)
		{
			Irrigation_Zone4.postUpdate("Active " + (Countdown_Zone4.state as DecimalType) + " minutes remaining")
	    	timer4 = createTimer(now.plusMinutes(1)) [|
			Countdown_Zone4.postUpdate(Countdown_Zone4.state as DecimalType - 1)
			]
		}
			
if (Countdown_Zone4.state as DecimalType == 0 && SprinklerSystemZone4.state == ON)
				{
				SprinklerSystemZone4.sendCommand(OFF)
				sendBroadcastNotification("Finished Watering Zone 4")
				}
end

//***************************************************************************


rule "IFTT rule"
when
    Item IFTTString received update
then
var item=IFTTString.state.toString.split(";").get(0)
//val time=IFTTString.state.toString.split(";").get(1)
val time = Integer::parseInt(IFTTString.state.toString.split(";").get(1))

if (item.contains("back garden"))
{
postUpdate(onHours4, time)
SprinklerSystemZone4.sendCommand(ON)
}

if (item.contains("back grass"))
{
postUpdate(onHours3, time)
SprinklerSystemZone3.sendCommand(ON)
}

if (item.contains("front garden"))
{
postUpdate(onHours2, time)
SprinklerSystemZone2.sendCommand(ON)
}

if (item.contains("front grass"))
{
postUpdate(onHours1, time)
SprinklerSystemZone1.sendCommand(ON)
}
end

//***************************************************************************

rule "GrassMoistures"
when
        Item FrontGrassMoisture received update
then	
		FrontGrassMoistureTime.postUpdate( new DateTimeType())
end




Garage Door rules

var Timer garageDoorTimer 
var Timer garageDoorOpenTimer
var Timer garageLightTimer

//*************************************************************************** Garage Door Rules Below********************************************************************


rule "Garage Door Open"
when
	Item GarageDoor received command UP
then

if (garageDoorTimer !== null)
	{
	garageDoorTimer.cancel
	garageDoorTimer = null
	}
	
	if (GarageDoorOpened.state != ON)
		{
		
		GarageDoorSwitch.sendCommand(ON)
			garageDoorTimer = createTimer(now.plusSeconds(25)) [|
			if (GarageDoorOpened.state != ON && GarageDoorClosed.state == ON)
				{
				GarageDoorSwitch.sendCommand(ON)
			    }
			]
		}
end
//********************************************************************



rule "Garage Door Close"
when
	Item GarageDoor received command DOWN
then

if (garageDoorOpenTimer !== null)
	{
	garageDoorOpenTimer.cancel
	garageDoorOpenTimer = null
	}
	
if (garageDoorTimer !== null)
	{
	garageDoorTimer.cancel
	garageDoorTimer = null
	}
	


	
	if (GarageDoorClosed.state != ON)
		{
			
			
		GarageDoorSwitch.sendCommand(ON)
			garageDoorTimer = createTimer(now.plusSeconds(25)) [|
			if (GarageDoorClosed.state != ON && GarageDoorOpened.state == ON)
				{
				GarageDoorSwitch.sendCommand(ON)
			    }
			]
		}
end
//********************************************************************




rule "Garage Door Stop"
when
	Item GarageDoor received command STOP
then

if (garageDoorTimer !== null)
	{
	garageDoorTimer.cancel
	garageDoorTimer = null
	}

	if (GarageDoorClosed.state != ON && GarageDoorOpened.state != ON)
		{
		GarageDoorSwitch.sendCommand(ON)
		}
		
end
//********************************************************************




rule "Garage Door State"
when 
	Item GarageDoorClosed received update	or
	Item GarageDoorOpened received update
then
Thread.sleep(500)
	if (GarageDoorClosed.state == ON && GarageDoorOpened.state == OFF)
		{
		GarageDoor.postUpdate(DOWN)
		sendBroadcastNotification("Garage Door has Closed!")
		GarageDoorState.postUpdate("Closed")
		
		if (garageDoorOpenTimer !== null)
	        	{
      			garageDoorOpenTimer.cancel
        		garageDoorOpenTimer = null
        		}
	
				garageLightTimer = createTimer(now.plusSeconds(30)) [|
				GarageLights.sendCommand(OFF)
				]
				

		}
	if (GarageDoorOpened.state == ON && GarageDoorClosed.state == OFF)
		{
		GarageDoor.postUpdate(UP)
		GarageDoorState.postUpdate("Open")
		}
	if (GarageDoorClosed.state == OFF && GarageDoorOpened.state == OFF)
		{
		GarageDoor.postUpdate(50)
		GarageDoorState.postUpdate("Ajar")
		}
		
end
//********************************************************************




rule "Garage Door Button Timer"
when
	Item GarageDoorSwitch received command ON
then
	createTimer(now.plusSeconds(2)) [|
	GarageDoorSwitch.sendCommand(OFF)
	]
end


//********************************************************************
	
rule "Garage Door Auto Close"
when 
	Time cron "0 0/1 21-5 1/1 * ? *"
then

if (garageDoorOpenTimer === null)
	{
	

if (GarageDoorAuto.state == ON)
	{
	if (GarageDoorClosed.state != ON)
		{
		sendBroadcastNotification("Garage door will shut in 5 minutes")
		garageDoorOpenTimer=createTimer(now.plusMinutes(5)) [|
		sendBroadcastNotification("Garage door is closing automatically")
		GarageDoor.sendCommand(DOWN)
		]
		}
	}
}
end


//********************************************************************
	
rule "Garage Door Auto Close Switch "
when 
	Item GarageDoorAuto received command OFF
then
	if (garageDoorOpenTimer !== null)
	{
	garageDoorOpenTimer.cancel
	garageDoorOpenTimer = null
	}
end



//********************************************************************




rule "Garage Door Opening"
when 
	Item GarageDoorClosed changed from ON to OFF
then
	sendBroadcastNotification("Garage Door has opened!")
	
	//if(now.getHourOfDay() > 16)
    //{
	GarageLights.sendCommand(ON)
	//}
	

	
end

//********************************************************************

rule "GarageDoorLightOff"
when	
	Item GarageLights received update OFF
then
	if (garageLightTimer !== null)
	{
	garageLightTimer.cancel
	garageLightTimer = null
	}
end

and blind.rules

rule "Lounge Blinds"
when
        Item AllLoungeBlinds received update
then
val percent = AllLoungeBlinds.state as Number	


LoungeBlinds1.sendCommand(percent) 
LoungeBlinds2.sendCommand(percent)
LoungeBlinds3.sendCommand(percent)

end

//***************************************************************************

rule "Main Bed Blinds"
when
        Item AllMainBlinds received update
then
val percent = AllMainBlinds.state as Number	

MainBedBlinds1.sendCommand(percent) 
MainBedBlinds2.sendCommand(percent)
MainBedBlinds3.sendCommand(percent)

end

//***************************************************************************

rule "All Blinds"
when
        Item AllBlinds received update
then
val percent = AllBlinds.state as Number	

LoungeBlinds1.sendCommand(percent) 
LoungeBlinds2.sendCommand(percent)
LoungeBlinds3.sendCommand(percent)
MainBedBlinds1.sendCommand(percent) 
MainBedBlinds2.sendCommand(percent)
MainBedBlinds3.sendCommand(percent)

end

//***************************************************************************
rule "Lounge status"
when
        Item LoungeBlindsStatus received update
then


createTimer(now.plusSeconds(5)) [|
LoungeBlindsLastOnline.postUpdate(new DateTimeType())
LoungeBlindsSettings.sendCommand(LoungeBlinds1.state as Number + 200)
LoungeBlindsSettings.sendCommand(LoungeBlinds2.state as Number + 400)
LoungeBlindsSettings.sendCommand(LoungeBlinds3.state as Number + 600)
]

end

rule "Main Bed status"
when
        Item MainBlindStatus received update
then

createTimer(now.plusSeconds(5)) [|
BedBlindsOnline.postUpdate(new DateTimeType())
MainBedBlindsSettings.sendCommand(MainBedBlinds1.state as Number + 200)
MainBedBlindsSettings.sendCommand(MainBedBlinds2.state as Number + 400)
MainBedBlindsSettings.sendCommand(MainBedBlinds3.state as Number + 600)
]


end

This is all just for your information. My rules are by no means streamlined, but they work, and have done so for the last 6 months or longer.

Thanks guys :grin:

Matt had a video. Here Matt is doing a new video’s on HA too now. Have you tried it yet.