Rachio Smart Sprinkler Controller

Guess that’s possible. I am still good on my end.

a new build is available at
https://github.com/markus7017/org.openhab.binding.rachio/blob/alpha2/target/org.openhab.binding.rachio-2.3.0-SNAPSHOT.jar

Markus,

I installed the new updated binding and so far it looks good. The only thing I noticed is that the image url does not provide the entire URL as we had discussed. This is what I see for image URL.

https://prod-media-photo.rach.io/

verified that the binding is running on OH 2.1, 2.2 and 2.3-SNAPSHOT (Dev)

verified that the JSON returned by the cloud api returns

..."imageUrl":"https://prod-media-photo.rach.io/"

need to investigate / contact Rachio support

alpha2 branch has been merged to master

  • https supported for inbound webhook events
  • more information in the zone event strings
  • image load requests are redirected to the binding to prevent a problem with the Rachio cloud
  • revised exception handling
  • disabled zones don’t create a thing

https://github.com/markus7017/org.openhab.binding.rachio/blob/master/target/org.openhab.binding.rachio-2.3.0-SNAPSHOT.jar

In addition the README is updated to include a how-to setup a reverse proxy based on NGINX or Apache. This makes the webhook events really secure.

Sample rule to catch zone events (replace rachio_zone_1_xxxxxxxx_1_zoneEvent with the connect item name):

var int totalRunTime = 0

/* ------- Alarm handler ----- */
rule "Zone started"
when
	Item rachio_zone_1_xxxxxxxx_1_zoneEvent changed
then
	var jsonString = rachio_zone_1_xxxxxxxx_1_zoneEvent.state.toString
	logDebug("RachioEvent", "Event triggered (JSON='" + jsonString + "')")
	
	var eventTimestamp = transform("JSONPATH","$.timestamp",jsonString);
	var eventType = transform("JSONPATH","$.type",jsonString)
	var eventSubType = transform("JSONPATH","$.subType",jsonString)
	var eventSummary = transform("JSONPATH","$.summary",jsonString)

	if (eventType == "ZONE_STATUS") {
		var zoneName = transform("JSONPATH","$.zoneName",jsonString)
		var zoneNumber = transform("JSONPATH","$.zoneNumber",jsonString)
		var runState = transform("JSONPATH","$.zoneRunState",jsonString)
		var runStart = transform("JSONPATH","$.startTime",jsonString)
		var runEnd = transform("JSONPATH","$.endTime",jsonString)
		var runDuration = transform("JSONPATH","$.duration",jsonString)
		var scheduleType = transform("JSONPATH","$.scheduleType",jsonString)
		logInfo("RachioEvent", eventTimestamp + " " + zoneName + "[" + zoneNumber + "]: " + eventSummary + "(type='" + scheduleType + "', state='" + runState + "')")
		if (eventSubType == "ZONE_COMPLETED") {
			totalRunTime = totalRunTime + Integer::parseInt(runDuration)
			logInfo("RachioZone", "Zone [" + zoneNumber + "]: start: " + runStart + ", end: " + runEnd + ", duration: " + runDuration + " => Total run time = " + totalRunTime)
		}
	} 
	else {
		// generic message
		logInfo("RachioEvent", eventTimestamp + " [" + eventSubType + "]: " + eventSummary)
	}

end

see openhab.log

2018-05-13 18:11:59.659 [INFO ] [e.smarthome.model.script.RachioEvent] - 2018-05-13T22:11:52Z Driveway-rechts[1]: Driveway-rechts completed watering at 06:11 PM (EDT) for 2 minutes.(type='FIXED', state='COMPLETED')
2018-05-13 18:11:59.683 [INFO ] [se.smarthome.model.script.RachioZone] - Zone [1]: start: 2018-05-13T22:09:55.968Z, end: 2018-05-13T22:11:55.968Z, duration: 120 => Total run time = 120

using a OH item for totalRunTime and making it persistent will provide the total run time (if you lile per zone and on the controller and you could combine this with a Garfana graph).

Sniplet 1 for HABpanel template / widget: show zone event and properties

<div class="text-left" ng-init="event=$eval(itemValue('rachio_zone_1_xxxxxxxx_1_zoneEvent'))"> 
Zone [{{itemValue('rachio_zone_1_F0038CC690BE_1_number')}}]: {{itemValue('rachio_zone_1_F0038CC690BE_1_name')}}<br/>
{{event.summary}}<br/>
Last run: {{event.startTime}} for {{event.duration}}s<p/>
</div>

Sniplet 2 - “dump” event attributes

<div class="text-left" ng-repeat="(key, value) in $eval(itemValue('rachio_zone_1_xxxxxxxx_1_zoneEvent'))">
{{key}}:{{value}}
</div>
<p/>

Good news:
Rachio support came back on the problem with missing mime types on image downloads:
“New images have the correct mime-type. This week we will be updating existing images with the correct mime-type. Thanks for pointing this out. The new images now with directly from the URL.”
This means
a) the OH community is helping Rachio to improve their product (this was the 2nd time)
b) I could remove the image loader servlet in a upcoming release of the binding (after Rachio fixed their database internally)

Next: I requested information how to catch the WEATER_INTELLEGENCE events. This would allow to track those events and process the information in a dashboard of Garfana histogramm.

1 Like

@Agbush, @KidSquid Any feedback / test results from your side?

Latest build:

Known issues

  • a access failure to the cloud (e.g. Internet connection is down) forces the thing to become offline (which is correct), but there is no recovery when the cloud connection was restored, so thing doesn’t become online
  • sometimes inbound webhook events are not processed (ignore due to “unknown device” / “unknown zone” messages)
  • device discovery sometimes fails - no clue why
  • timestamps are not adapted to local timezone, even the Rachio cloud returns different formats - all of them need to be unified

Open to discuss

  • simplify schema of item naming (currently they include the mac address of the controller, which makes rules & widget code installation specific)
  • do we need seperated zone events or is a consolidated device event channel the better way. Even if I want to filter by zone this information is included in the zone events (see sample sniplets). Having only a single event channel per device also means a way easier way to catch all zone events (one rule rather than one for the device and one for each zone).

Need help

  • Who could help to develop a cool HABpanel widget?
  • Does anyone already has a Gen3 controller? and/or Rachio Flow Meter?
  • Does anyone has attached sensors to the controller?

Next step: with beta1 I’ll move to the ESH IoT market to get more testers.

So did this project die out? Haven’t seen anything for a couple of months.

Squid

Hi @KidSquid,
no, just a matter of time. In between I got feedback from users that both setups (polling + event drive through http proxy) work as well as the enhanced security functions. Rachio is blocking on the event information for things like rain skip, seasonal shift etc.

So the version in the master branch is working fine (even one user tried with Gen3), the beta1 branch is work-in-progress. Let me know if you want to try with the reverse proxy setup (the doc describes ngix and apache). My 2 controllers are working since weeks without problems.

1 Like

Any update on the event information?

I’ve created a status board using HABpanel and would love to add a section about the sprinklers.

Squid

Hi @KidSquid,

I’m not sure what your are asking about? The event interface is implemented since various releases (see above). Get event events on zone activities etc., but not on rain skip, seasonal shift etc. (Rachio didn’t replied on those questions. maybe they want to keep that information close, because that would allow to build a similar app).

setup if the reverse prox is in the README.MD

@markus7017

I got a response back from the CTO of Rachio indicating that the Skip Alerts are available through their webhook.

/public/notification/webhook_event_type · Rachio

Is this something that could be added in?

Squid

I know that call, but more or less 100% that it doesn’t list the rain skip etc. event type. I need to check again. Keep you posted.

@KidSquid I verified the result, if you call the url you get

[{"id":5,"name":"DEVICE_STATUS_EVENT","type":"WEBHOOK"},
"id":10,"name":"ZONE_STATUS_EVENT","type":"WEBHOOK"},
"id":6,"name":"RAIN_DELAY_EVENT","type":"WEBHOOK"},
"id":7,"name":"WEATHER_INTELLIGENCE_EVENT","type":"WEBHOOK"},
"id":9,"name":"SCHEDULE_STATUS_EVENT","type":"WEBHOOK"},
"id":11,"name":"RAIN_SENSOR_DETECTION_EVENT","type":"WEBHOOK"},
"id":8,"name":"WATER_BUDGET","type":"WEBHOOK"},{"id":12,"name":"ZONE_DELTA","type":"WEBHOOK"},
{"id":14,"name":"DELTA","type":"WEBHOOK"}]

That’s what I use to register for events:

public static final String WHE_DEVICE_STATUS = "5"; // "Device status event has occurred"
public static final String WHE_RAIN_DELAY = "6"; // "A rain delay event has occurred"
public static final String WEATHER_INTELLIGENCE = "7"; // A weather intelligence event has has occurred
public static final String WHE_WATER_BUDGET = "8"; // A water budget event has occurred
public static final String WHE_SCHEDULE_STATUS = "9";
public static final String WHE_ZONE_STATUS = "10";
public static final String WHE_RAIN_SENSOR_DETECTION = "11"; // physical rain sensor event has coccurred
public static final String WHE_ZONE_DELTA = "12"; // A physical rain sensor event has occurred
public static final String WHE_DELTA = "14"; // "An entity has been inserted, updated, or deleted"
   
        String jsonData = "{ " +
                "\"device\":{\"id\":\"" + deviceId + "\"}, " +
                "\"externalId\" : \"" + externalId + "\", " +
                "\"url\" : \"" + callbackUrl + "\", " +
                "\"eventTypes\" : [" +
                "{\"id\" : \"" + WHE_DEVICE_STATUS + "\"}, " +
                "{\"id\" : \"" + WHE_RAIN_DELAY + "\"}, " +
                "{\"id\" : \"" + WEATHER_INTELLIGENCE + "\"}, " +
                "{\"id\" : \"" + WHE_WATER_BUDGET + "\"}, " +
                "{\"id\" : \"" + WHE_ZONE_DELTA + "\"}, " +
                "{\"id\" : \"" + WHE_SCHEDULE_STATUS + "\"}, " +
                "{\"id\" : \"" + WHE_ZONE_STATUS + "\"}, " +
                "{\"id\" : \"" + WHE_RAIN_SENSOR_DETECTION + "\"}, " +
                "{\"id\" : \"" + WHE_DELTA + "\"} " +
                "]" +
                "}";
        httpApi.httpPost(APIURL_BASE + APIURL_DEV_POST_WEBHOOK, jsonData);

So in fact I register for everything, receive zone events, but no WEATHER_INTELLEGENCE, WARTER_BUDGET, RAIN_DELAY. Do know about RAIN_SENSOR, because I don’t have one.

Additional information is more than welcome.

Did you tried the other event functions and reverse proxy?

So just to make sure I understand you correctly…

The following calls do not respond with any information?

public static final String WHE_RAIN_DELAY = "6"; // "A rain delay event has occurred"
public static final String WEATHER_INTELLIGENCE = "7"; // A weather intelligence event has has occurred
public static final String WHE_WATER_BUDGET = "8";

nope, the binding dumps the event information if it receives events, which are currently not implemented, but I don’t see any of those events

this thread includes the communication I had with Franz from Rachio

@markus7017

Please take a look at the reply below…

I did. So maybe the platform sends those events after they have been triggered correctly. Maybe my initialization is wrong. However, the other events work fine.

I posted the code to the referred thread with Franz.