How To: Integrate Custom openHAB Cloud with IFTTT

Hi all,

New to the openHAB automation scene, and I am in the midst of setting up my custom openHAB cloud with IFTTT, since it doesn’t seem to be working on the openHAB cloud hosted at myopenHAB. There doesn’t seem to be a guide on how to integrate IFTTT with a custom openHAB cloud, so I figure I’d pay it forward by writing down the steps I took.

First things first, in case you are confused, you cannot use the well-known openHAB IFTTT service. That is hardcoded to use myopenHAB. Instead, you’re going to have to create a new unpublished service at IFTTT Platforms, much like you have to do with integrating a custom openHAB cloud instance with Google Assistant or Amazon Alexa.

Before creating the service, there are some setup steps to make testing everything easier. ssh into your openHAB cloud, and follow the following steps:

  1. Generate a Client ID and Client Secret that’s shared between IFTTT and your custom openHAB cloud. I used Python 3’s “secure” library to generate two custom strings. Run the python command, then, in the shell, type in

    >>> import secrets
    >>> secrets.token_hex(32)
    >>> secrets.token_hex(32)
    

    You can use the first as the Client ID, and the second one as the Client Secret.

  2. Optional: Create a new registered demo user on your custom openHAB cloud so that you can test IFTTT’s integration. This may involve changing "registration_enabled": true in your config.json. Fill out the openHAB cloud’s sign-up form, and set the openHAB UUID and secret to something random (it won’t be used).

    Technically, you can use an existing account, but I prefer to create a new one since the credentials will end up on IFTTT and I can use the provided custom openHAB cloud tests.

  3. Optional: Create fake items in mongodb so that IFTTT tests can change the item states successfully. Open mongodb’s CLI with mongo, and follow the steps:

    1. Run use openhab to change the database.
    2. Run db.openhabs.find() to find the list of openHABs registered in the cloud. Find the openHAB that you created by comparing uuid and secret fields to the random openHAB UUID and secret you used. Copy the _id associated with that object.
    3. Run the following, replacing _id
      >>> db.items.insert({ openhab: ObjectId("_id"), name: "Light_GF_Kitchen_Table", status: "OFF" })
      >>> db.items.insert({ openhab: ObjectId("_id"), name: "DemoSwitch", status: "ON" })
      >>> db.items.insert({ openhab: ObjectId("_id"), name: "Temperature", status: "21" })
      
      Note that we got the item names from some sample code in the custom openHAB code (see routes/ifttt.js in the GitHub repository. These are items that our custom openHAB cloud will make available to IFTTT for the IFTTT tests.

Go ahead and create a new service at IFTTT Platforms. There’s a “General” tab in the UI that asks you information about the “Service name”, “Description”, etc… None of that really matters because the service will not be submitted. What you really want to do is go to the “API” tab and follow these steps:

  1. Fill out the “IFTTT API URL” field to “https://[your openHAB cloud URL]”.
  2. Note the IFTTT Service Key. You’ll need it further down.
  3. In the Authentication page, mark the radio button “My API has users with non-expiring OAuth2 access tokens”
  4. Set the “Client ID” and “Client Secret” to what you generated above.
  5. Set the “Authorization URL” to “https://[your openHAB cloud URL]/oauth2/authorize”
  6. Set the “Token URL” to “https://[your openHAB cloud URL]/oauth2/token”
  7. Optional: Add the demo credentials that you created previously.

Now, we need to make IFTTT aware of all of the possible Triggers and Actions offered by our custom openHAB cloud. This involves basically recreating the capabilities that main IFTTT openHAB service offers, except using our own endpoints…

  1. Go to “Triggers”, remove the default “A new thing was created” Trigger, and add the following 3 Triggers:
    • “Item state changes” with description “This Trigger fires every time an item changes its state to a value you specify.” and API endpoint itemstate.
    • “Item state raises above” with description “This Trigger fires every time an item’s state raises above a value you specify and works with any number item.” and API endpoint item_raised_above.
    • “Item state drops below” with description “This Trigger fires every time an item’s state drops below a value you specify and works with any number item.” and API endpoint item_dropped_below.
  2. Go to “Actions”, remove the default “Create a new thing” Action, and add the following Action:
    • “Send a command” with description “This Action will send a command to one of your openHAB items.” and API endpoint command.
  3. Go back through all of the Triggers and Actions you added, and add a new field (i.e., “Trigger field” and “Action field”). When creating IFTTT applets, this allows IFTTT to know what openHAB Item to respond to (for Triggers) or to act on (for Actions). The field should have the label “Which item?” with “Key name” set to item, “Input Type” set to “Dropdown list”, and “Data source for dropdown list” set to “Retrieve list items from my service”.
  4. Go to the “Item state changes” Trigger and add another field with label “What status?”, “Key name” set to status, and “Input type” set to “Text input.”
  5. Go to the “Item state raises above” Trigger and add another field with label “Above what value?”, “Key name” set to value, and “Input type” set to “Text input.”
  6. Go to the “Item state drops below” Trigger and add another field with label “Below what value?”, “Key name” set to value, and “Input type” set to “Text input.”
  7. Go “Send a command” Action and add another field with label “Command to send”, “Key name” set to command, “Action field type” set to “Text input”, and the option “Short text (140 characters or fewer)” checkmarked.

Now, you’ll need to make some changes in your custom openHAB cloud. ssh into it, and follow these steps:

  1. Open the mongodb CLI by running mongo and enter these commands

    >>> use openhab
    >>> db.oauth2clients.insert({ clientId: "<CLIENT-ID>", clientSecret: "<CLIENT SECRET>"})
    >>> db.oauth2scopes.insert( { name : "ifttt", description: "Access to openHAB Cloud specific API for IFTTT", } )
    
  2. Open your cloud’s config.json and add the IFTTT service key:

    "ifttt" : {
    "iftttChannelKey" : "[IFTTT SERVICE KEY GOES HERE]",
    "iftttTestToken" : ""
    },
    

    Note that IFTTT “channel key” and “service key” are interchangeable. Also, you will optoinally fill out “iftttTestToken” later below.

  3. Restart the custom openHAB cloud server.

Optional: Now, go back to the “API” tab, and follow the steps:

  1. Go to “Authentication Test” and run “Begin test”. You should be led to your custom openHAB cloud logged in as your demo user asking you if you want to grant IFTTT access. This means that it is successful.
  2. In the successful results, find the “Request access token” step. Look at the Response Body, and find the value for the key access_token. You will need to go back to your custom openHAB server, add that value as the value for “iftttTestToken”, and restart the server. Thanks to Setup your own openhab-cloud (myopenhab) server/instance for the tip.
  3. Go to “Endpoint Tests” and run “Begin test”. Note that the triggers and actions tests should fail because the custom openHAB cloud did not reformat the responses properly, but if you through the failed tests, you’ll at least see that every requested returned a successful response (i.e., 200).

Well, that’s it! Now you can go create your own IFFTT at ifttt.com/create, using the “Service name” to find your service. If this was helpful or if you run into any problems, please comment :slight_smile:

7 Likes

Great stuff! I admittedly won’t be doing this as I’ve reduced my dependency on IFTTT, but I’m grateful for anyone who jumps in with a new contribution.

What are you using to host for your cloud? I think some people might be interested in that, particularly with respect to performance and security.

IFTTT support had to be turned off just over a week ago, because the traffic was overloading myopenhab’s mongodb database. I’m not at all an expert on this, but I’ll be curious as to how your custom cloud solution does over time. I imagine it’ll be fine, but it’s worth monitoring.

Welcome!

For hosting the cloud, I have a small DigitalOcean droplet for running CentOS. It’s worth it for the stability; I recently wasn’t able to add items to myopenHAB (thanks for clarifying why in [SOLVED] openHAB Cloud expose items, I need guidance), and I didn’t want to wait for the problem to be fixed so I created my own cloud. Performance isn’t an issue, since it’s just me and the code is very simple. Security, however, is more of an open question… I don’t think there’s much to stop malicious behavior like DDoSing. But aside from network overload, I imagine it has the same vulnerabilities as myopenHAB, since the codebase is identical.

I read about IFTTT being blocked in myopenHAB, so I created a pull request for IFTTT realtime updates with the intent of reducing IFTTT polling (see Github). But Dan commented saying that the problem was primarily about Item and Event updates, and IFTTT polling just adds to it. In any case, I do hope the problem gets fixed soon.

1 Like

Is this a literal command or do we substitute the previous test ID/Secret we created for testing?

`>>> db.oauth2clients.insert({ clientId: "<CLIENT-ID>", clientSecret: "<CLIENT SECRET>"})`

I have gone though the process (substituting it) but when I try the test authentication from IFTTT API i get

Error: Unauthorized client
at validated (/var/www/openhab/openhab-cloud/node_modules/oauth2orize/lib/middleware/authorization.js:136:36)
at Query.<anonymous> (/var/www/openhab/openhab-cloud/routes/oauth2.js:111:20)
at /var/www/openhab/openhab-cloud/node_modules/kareem/index.js:177:19
at /var/www/openhab/openhab-cloud/node_modules/kareem/index.js:109:16
at _combinedTickCallback (internal/process/next_tick.js:73:7)
at process._tickCallback (internal/process/next_tick.js:104:9)

Correct; you do replace <CLIENT-ID> and <CLIENT SECRET> with what you generated above. And this is a command (starting with db.oauth2clients...) that you enter into the shell that’s opened after executing the command mongo. You’ll know you’ve entered the shell when you see the lines in the terminal prefixed with >>>. Be sure to run the command use openhab to change the database before running any commands prefixed with db.

Yeah, I got all that, i think i made a typo on the actual ID or secret. Deleted the record and re-added and it is working now :slight_smile: Thanks so much for a great writeup. It was a bit daunting but I got there in the end. Good work!

You are my hero. I was really sad about not being able to use IFTTT with openhab. This is so great! Thank you!

Thanks for the guide.
I write because I have a problem.

After I finished, I managed to connect properly from IFTTT to my Custom OpenHab, but after that when I try to create an applet I get the “Options not available” message in the items drop-down.
Into my openhab I can to see all my items…

I’m looking for an idea about to resolve this problem after very much houres of work

Can you help me please?

After log into SSH, and run Python, “import secrets” and it’s doing me that:

import secrets
Traceback (most recent call last):
File “<stdin”, line 1, in <module
ImportError: No module named secrets

Help?

What version? secrets was introduced in Python 3.6 (run python --version)

https://docs.python.org/3/library/secrets.html

2.7 How to update?

1 Like

Python 2 is totally end of support in January. Some systems have a python3 command with a newer version.
What operating system (Linux variant, I assume) & version are you running?

I running Openhab 2.4.0 on RaspberryPi 3.
My PC: Windows 10

I guess you are running Raspbian or Raspbian Lite then? I believe the newest version (Buster) has Python 3 by default. The older version has a python 3 version in its repo, but not new enough for you. Depending on how large your OH system is, it might be a good time to update the OS.

Yes, I am using Raspbian. What do you mean update my OS? to what?

To the newer version of Raspbian.

Okay after upgrading my Resbian newsest version , I also upgrade my Python and now when I run in my SSH ‘python3.6 --version’ it’s saying that my Python is 3.6, but when I run ‘python --version’ it’s saying 2.7, how can I delete the 2.7 and why I still can’t run in my python ‘secrets’ ?

You likely cannot delete the 2.7 because other pieces use it. I think the following commands can change which version is referenced by the python command.

sudo update-alternatives --insytall /usr/bin/python /usr/bin/python2.7 1
sudo update-alternatives --insytall /usr/bin/python /usr/bin/python3.6 2
``
From https://raspberry-valley.azurewebsites.net/Python-Default-Version/

Hi, thank you so much, now when I ‘python --version’ it’s saying 3.5.4
But still when I trying to do import secrets it’s doing me this:

Traceback (most recent call last):
  File "<stdin", line 1, in <module
ImportError: No module named 'secrets'

what can I do about it?

You said you updated to the latest Raspian which has Python 3.7. I don’t know where 3.5 came from but that is too old.