Using Dropbox and Hazel to add state variables and logic conditions to IFTTT

Abstract

This post describes how you can extend the Internet service IFTTT (If This Then That) using Dropbox and Hazel to handle logic conditions and state variables.

The functionality is exemplified on a system for controlling Philips hue lights.

A prerequisite for using this system is that you have a computer available that is always on.

The iPhone app Drafts is used for manually controlling the lights.

Introduction

IFTTT is an Internet service that lets you create connections between various Internet services using the statement:

If this then that,

where this is a trigger from one Internet service and that is an action by another Internet service. The different Internet services are called channels.

Examples of channels are Facebook, Twitter, and Evernote, but there are also a Date and Time channel that includes triggers for certain days, dates and times and an Email channel that can be triggered by emails from your registered email account and can act on other triggers by sending an email to you.

For a more complete description of IFTTT and its terminology, see their about page.

An example of an application for IFTTT is to autosave all your Instagram photos to your Dropbox account.

Besides handling emails and photos, IFTTT can also control physical devices through the Belkin WeMo Motion and WeMo Switch channels and the Philips hue channel.

So IFTTT is very useful when one Internet service triggers an action provided by another Internet service. However, there are shortcomings with IFTTT in its current implementation:

  • Triggers cannot depend on any logic conditions
  • State variables cannot be handled

For example, let’s say you would like to turn on your Philips hue lights every morning when you wake up. However, you don’t want to turn on the lights if the sun is already up. With IFTTT you cannot create a condition like

if sun is down turn on my lights every day at 6.00 AM

To provide a solution for the two drawbacks discussed above, we have to add a layer of indirection, since

All problems in computer science can be solved by another level of indirection[1].

To get this additional level of indirection, we let IFTTT save text files to our Dropbox account. Then those text files are processed by the Mac tool Hazel. Hazel

  • processes the files saved to Dropbox by IFTTT
  • creates new files that defines the state (for instance the file sun_has_set)
  • checks if logic conditions are met (for instance, is the file sun_has_set available?)
  • emails IFTTT to trigger actions

Thus, by taking the extra steps of storing files to Dropbox and processing those files using Hazel, we now have the possibility to add logic conditions, determine the value of state variables and perform several actions for one trigger.

Of course, to add the extra level of indirection, we, with this setup, need a computer that is continuously running and responding to the file creation events generated by IFTTT in the Dropbox folder. This system is created for a Mac, continuously running the app Hazel to handle the file events. However, a similar extra level of indirection is probably possible to create using a continuously running Linux of Windows computer, running some file monitoring software similar to Hazel.

To trigger actions manually, we should also add files to Dropbox instead of directly triggering actions using IFTTT. Thereby we make sure that the state variables (stored as files in Dropbox) are properly updated all the time.

The following sections describe how to setup the Dropbox folders, define the IFTTT recipes, and setup the Hazel rules (including the AppleScripts to send emails to IFTTT). Furthermore, in the section called Drafts setup, it is shown how to setup the Drafts app to manually control the system.

The particular setup described in this post, shows how Philips hue lights can be controlled using IFTTT, Dropbox and Hazel. However, the same methodology can be used to control anything that can be controlled by IFTTT.

Dropbox setup

In our Dropbox folder we setup the folder structure that IFTTT writes to and that Hazel monitors. The base folder ifttt has two subfolders, incoming and status, as shown in the graph below:

ifttt
  |-- incoming
  |-- status

Since IFTTT writes to any Dropbox folder, you can setup the folder structure among your private Dropbox folders.

IFTTT writes only to the incoming folder, whereas Hazel monitors both folders.

IFTTT setup

The IFTTT term for the if this then that trigger-action combination is recipe. When we setup IFTTT we can distinguish between two different types of recipes:

Dropbox file creation recipes

These recipes create files in the incoming Dropbox folder. The sunrise and sunset recipes creates the files sunrise and sunset, respectively. The other recipes are triggered at specific times and generates files named according to the specific times. For instance, there is one recipe that creates the file every_day_at_0100 in the incoming folder every day at 01:00 AM.

The recipes in the following table are used to provide status information and to trigger potential actions.

# Trigger Channel Trigger Action Channel Action
1 Weather Sunrise Dropbox Create a text file (sunrise)
2 Weather Sunset Dropbox Create a text file (sunset)
3 Date & Time Every day at (01:00) Dropbox Create a text file (every_day_at_0100)
4 Date & Time Every weekday at (Mon – Fri, 06:00) Dropbox Create a text file (every_weekday_at_0600)
5 Date & Time Every weekday at (Sat – Sun, 08:00) Dropbox Create a text file (every_weekend_at_0800)
6 Date & Time Every weekday at (Mon – Fri, 09:30) Dropbox Create a text file (every_weekday_at_0930)

Tagged IFTTT email recipes

The recipes in this section trigger specific actions, by sending emails to IFTTT with special tags in the subject line. Depending on the tag, a different action is performed. In all recipes we use the Email channel and the Send IFTTT an email tagged trigger. An advantage of triggering actions using the Email channel is that those recipes are triggered as soon as IFTTT receives the email. Most other channels have a polling period of 15 minutes.

The table below summarizes the tagged IFTTT email recipes.

# Trigger Channel Trigger Action Channel Action
1 Email Send IFTTT an email tagged (TurnOnAllLights) Philips hue Turn on lights (All lights)
2 Email Send IFTTT an email tagged (TurnOffAllLights) Philips hue Turn off lights (All lights)

The figure below shows the trigger and action settings for recipe 2 in the table above (“Turn off lights”).
Trigger and action settings for the Turn off the lights recipe.

Hazel setup

Hazel monitors the Dropbox folders incoming and status. The rules in the incoming folder are checking all the files created by IFTTT (and also created by Hazel) and sends IFTTT commands by email, if all conditions are met for the command to be performed. The rules in the status folders makes sure that only one status file of each category is available in the status folder at each time. For instance, only one of the files sun_has_setand sun_has_risen is available at each instance.

Rules in the incoming folder

The following rules are available in the incoming folder:

  1. Turn on all lights
  2. Turn off all lights
  3. Sunrise
  4. Sunset
  5. Switch off all lights at 01:00
  6. Turn on all lights every weekday at 06:00, if sun has not risen
  7. Turn on all lights every weekend day at 08:00, if sun has not risen
  8. Turn off all lights every weekday at 09:30
  9. Don’t do anything – only trash the incoming file

Of all the rules above, it is actually only the first two rules that sends command via email to IFTTT. The rest of the commands tests a condition and/or creates a status file and then creates a new file in the incoming folder that is executed by one of the first two rules.

The following subsections describe the details for each rule.

Turn on all lights rule

The setup of this rule is shown in the figure below.
Hazel rule to send IFTTT and email to turn on all lights.
The rule is triggered by the existence of the file turn_on_all_lights in the incoming folder. When triggered, the first command is an AppleScript to send IFTTT an email to turn on all the Philips hue lights. Then the file turn_on_all_lights is moved to the status folder and renamed to all_lights_are_on.

The AppleScript is shown below.
The AppleScript to send IFTTT and email to turn on all lights.
First an email message to trigger@ifttt.com with the subject #TurnOnAllLights is created. Then this email is sent.
The email account you send this email from should be the same as you have registered for the IFTTT Email channel.

Turn off all lights rule

The rule to turn off all lights is similar to the rule to turn on all lights. Below you see the Hazel rule.
The Hazel rule to turn off all lights.
The rule is triggered by the existence of the file turn_off_all_lights. When triggered, first an AppleScript is run. This script is similar to the script above for turning on the lights, with the exception that the subject now is #TurnOffAllLights. After the script has run successfully, the trigger file is moved to the status folder and renamed to all_lights_are_off.

Sunrise rule

This rule first moves the trigger file sunrise to the status folder and renames it to sun_has_risen. Then the file sun_has_risen is copied to the incoming folder and renamed to turn_off_all_lights. When Hazel detects the turn_off_all_lights file in the incoming folder, the Turn off all lights rule above is triggered.
The Hazel rule run at sunrise.

Sunset rule

This rule is similar to the Sunrise rule above. However, this rule is triggered by the file called sunset and it moves that file to the status folder and renames it to sun_has_set and then copies the sun_has_set file to the incoming folder and renames the file to turn_on_all_lights.
The Hazel rule run at sunset.

Switch off all lights at 01:00 rule

This rule is really simple. It is triggered by a file called every_day_at 0100. This file is then renamed to turn_off_all_lights that will trigger the Turn off all lights rule above.
The Hazel rule that turns off the lights at 01:00 every night.

Turn on all lights every weekday at 06:00, if sun has not risen rule

This rule demonstrates how to check for the existence of a status file. The rule is triggered by the existence of the file every_weekday_at_0600 in the incoming folder and that the following shell script runs successfully.
The Hazel rule run every weekday at 06:00 to turn on all lights, if the sun has not risen.
The shell script uses the command find to check if the file sun_has_set is available in the status folder. If that file exists the command and, thus, the shell script is successful and the rule is triggered.
Embedded shell script detecting whether the file sun_has_set exists in the status folder.
If the two files exists, and, thus, the rule is triggered, the rule renames the every_weekday_at_0600 file to turn_on_all_lights. This will trigger the Turn on all lights rule above.

Turn on all lights every weekend day at 08:00, if sun has not risen rule

This rule is similar to the rule above, except that the trigger file is every_weekend_at_0800. Otherwise the embedded shell script and the renaming operation are the same as for the previous rule.
The Hazel rule run every weekend day at 08:00 to turn on all lights, if the sun has not risen.

Turn off all lights every weekday at 09:30

This rule looks for the existence of the file every_weekday_at_0930 and then renames the file to turn_off_all_lights.
Hazel rule triggered by the existence of the file every_weekday_at_0930 that turns off all the lights.

Don’t do anything – only trash the incoming file

Finally, this is the last rule in the incoming folder. It is triggered by any file (that has not been processed by any other rules) and only moves the file to Trash.
Hazel rule run on any files not previously processed. Those files are moved to Trash.

Rules in the status folder

The rules in the status folder removes the complementary status file when a new file is added to the status folder. For instance, only one of the files sun_has_set and sun_has_risen should be available at each instance.

The following rules are available for the status folder:

  1. Remove all_lights_are_on when all_lights_are_off is set
  2. Remove all_lights_are_off when all_lights_are_on is set
  3. Remove sun_has_risen when sun_has_set is set
  4. Remove sun_has_set when sun_has_risen is set

The subsections below briefly describe the different rules.

Remove all_lights_are_on when all_lights_are_off is set

This rule is triggered by the existence of the all_lights_are_off file in the status folder.
The Hazel rule run with the all_lights_are_off file is created in the status folder.
The embedded shell script only removes all files of the pattern all_lights_are_on*. It is useful to include the asterisk, as sometimes a few copies of the all_lights_are_on file is created in your status folder. This happens when the Turn on all lights rule has been triggered more than one time before a Turn off all lights rule is triggered.
The embedded shell script to remove the files all_lights_are_one*.

Remove all_lights_are_off when all_lights_are_on is set

This rule is the same as the rule Remove all_lights_are_on when all_lights_are_off is set, except that the rule is triggered by the existence of the file all_lights_are_on and that it is the all_lights_are_off file that is removed.

Remove sun_has_risen when sun_has_set is set

This rule is the same as the rule Remove all_lights_are_on when all_lights_are_off is set, except that the rule is triggered by the existence of the file sun_has_set and that it is the sun_has_risen file that is removed.

Remove sun_has_set when sun_has_risen is set

This rule is the same as the rule Remove all_lights_are_on when all_lights_are_off is set, except that the rule is triggered by the existence of the file sun_has_risen and that it is the sun_has_set file that is removed.

Drafts setup

If you manually generate the files turn_on_all_lights and turn_off_all_lights in the incoming folder, Hazel automatically creates the status files all_lights_are_on and all_lights_are_off, respectively, in the status folder. Thus, you always get the correct status set if you control you lights manually by creating the files in the incoming folder.

One easy way of creating those Dropbox files from you iPhone is to use the Drafts app. With the Drafts app you just create the two text files turn_on_all_lights and turn_off_all_lights.
The Drafts app on the iPhone, with the two files turn_off_all_lights and turn_on_all_lights.
Then create a Dropbox action in Drafts that saves the selected text file to the right Dropbox folder, /ifttt/incoming. Name it to something like “Save to IFTTT”.
The Drafts action to save a file to the Dropbox folder /ifttt/incoming.

Now, in the Drafts app on your iPhone (or iPad) you can tap the turn_on_all_lights file and then select the “Send to IFTTT” action from the action menu. Then your file will immediately be sent to the Dropbox folder and synced to you computer, where Hazel recognizes the new file and triggers the Turn on all lights rule. Isn’t this a nice way of using the Internet for turning on a light bulb, instead of just simply flipping the light switch on the wall!? 😉

4 comments

  1. The shell scripts embedded in the Hazel rules were updated to use /bin/bash, as this is the default shell for Hazel version 3.1.

  2. Updated the process to use AppleScripts for sending emails to IFTTT. The AppleScripts are less intrusive than the Automator workflows, as the messages are sent without the message window popping up.

  3. Totally awesome! Have you run across a way to do this using Android and/or Linux apps in addition to the IFTTT email channel? The lack of simple boolean logic support in IFTTT is shocking. Why hasn’t someone created a channel for state storage that can be read and set by other IFTTT channels?

    1. Thank for your comment!
      No. I have not seen any way of doing this using Android and/or Linux apps. However, I must admit that I haven’t been looking in that direction either.

Write a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.