IFTTT (If this then that) Service

Started by HeneryH, December 04, 2017, 11:30:20 AM

HeneryH

Anyone ever tried to have the gateway interact with IFTTT service?  I haven't even remotely begun looking into the technical details but I assume there is some sort of API to the service that can be taken advantage of.

The end goal:

I have a marina property and with the winter freeze coming soon, I want to automate the de-icer system.  If the water freezes around a pile then the tide rises, it could jack the piles right out of the ground.

I created a waterproof solar charged super-cap Mot with a variant of the WeatherMot so that it uses a submersible thermometer ( https://www.adafruit.com/product/381 ) that I intend to float in the water near the docks.  Float the Mot with the temp probe dangling down about 12" sub-surface.  This currently reads the below surface water temperature and reports it back to the Gateway.   Just like a regular WeatherMot but I replaced the code to use the  Dallas Temperature Control Arduino library rather than the BME 280.

I also built a SwitchMot (while I totally f'ed the cover plate due to a build-error and having to break it apart to fix it, it still works headless without the plate) that I intend to switch the de-icer.  I put the 120v in an outdoor enclosure with GFCI protections.

Next is the hopeful simple step of connecting the two...  If sub-surface water temp goes below x then turn the de-icer on.

My quick looks around the forum and docs didn't find any hits. 

Any suggestions for further reading or hints on how to connect the two?

Thanks

HeneryH

Since the Gateway doesn't support IFTTT in its core feature set, I think I am going to need to use the IFTTT service to do what I am looking for.

If remote thermometer drops to less than x degrees, then turn on the de-icer.
If remote thermometer rises above y degrees, then turn off the de-icer.

Still at the very early stages of this.  I think I easily use the email notification from the gateway to trigger the IFTTT event but then in order to react to the event I need an action.

Can the gateway take a URL as a post and perform an action like turning on a SwitchMot?

HeneryH

Any way to remotely (non-human) cause an action to a device? 

While I can get events detected in IFTTT, without a way to remotely take action I am stuck. 

Felix

IFTTT - whoever came up with that acronym just reinvented the IF statement. Just like "IOT" it's a cringeworthy butchery of technical terms.

If you're looking for LEGO blocks approach of putting stuff together, then maybe other projects are more appropriate.
It will require extensive work to make drag and drop (aka "visual programming") for non-programmers possible.

In the 9.0 release you will be able to post data via URL. But not trigger actions, not yet at least. I can perhaps add that feature as well.

The "IFTTT" concept is supported if you know a little javascript :)
There are already given examples of doing something based on something else, that's if this then that. You can do anything you want actually, many others have demonstrated how easy it actually is to duplicate an event and trigger an action based on a custom metric value or some other need.


HeneryH

I took some code from another user (Brad) to allow incoming SMS messages to trigger actions.

Brad wrote a node.js server that listens for incoming SMS messages then sends socket.io messages over to the gateway.js.

I am hacking his code to help me do what I need.

Tech question...  The gateway.js has code in it to check if incoming socket connections originate from localhost.

When I connect from my sms_gateway.js to the gateway.js, the connections are being recognized by gateway.js as coming from 192.168.xx which is localhost but not in the 127.0.0.0 address so it is failing the check.

Anyone know how to get my new sms_gateway.js to connect to the gatway.js in such a way as the originating IP address is set to localhost rather than its real IP?

Felix

Quote from: HeneryH on November 19, 2018, 10:48:41 AM
192.168.xx which is localhost
How is that possible?

QuoteWhen I connect from my sms_gateway.js to the gateway.js

Where does sms_gateway.js live and how does it connect to gateway.js?

HeneryH

Quote from: Felix on November 19, 2018, 01:02:39 PM
How is that possible?
The sms_gateway.js server is running on the same machine as gateway.js so it has the same IP address.  The problem is that even though they are on the same host (RaspberryPi), the gateway.js only accepts inbound messages from localhost.  I hardcoded in the IP address of the Pi into the check for now.

Quote from: Felix on November 19, 2018, 01:02:39 PMWhere does sms_gateway.js live and how does it connect to gateway.js?
It is a separate node.js application running as a peer of the gateway.js application.

I'm trying to emulate the socket.io protocols to make the gateway do various tasks.

Current state of the effort:

  • I manually edited the gateway.js connection error checking to allow connections to the gateway from the IP address of the gateway itself (ie I added 192.168.1.xx to the allowable inbound connections check.
  • I created a new sms_gateway.js app that uses the Twilio service to listen for incoming SMS actions then brute force jams messages across the socket.io to the gateway.js app.  The sample code I started from was based on the GarageMot so I had to hack some stuff in an embarrassing manner.
  • The first and yet only hack I changed was to convert an inbound "ON" SMS message and jam a BTN0:1 message to the gateway which then turns the SwitchMot on.
  • The GarageMot and SwitchMot protocols are suffiently different that I need to learn more and get beyond the very crude hack-1. 
  • The sms_gateway.js app tries to check the current state of the Moteino on startup and I am now trying to get a basic STS message from the SwitchMot to tell me the current state of each button.

This is very early in my hacking of this and I am not sure about the way the socket protocols correlate to the serial port protocols which correlate to the metrics.js.  I'm trying to map it all out on paper now.

Getting the Switch to turn on in response to the SMS was a nice start but I need to really clean things up.

Felix

Not sure why would you go through the effort to receive SMSes to turn on a light? Is that some automated SMS from some other system?
If not, then the simple UI interface exists to make it easy for the user to turn something ON/OFF.
Events can be used to control things (lights) automatically.

Anyway, the gateway app rejects non localhost connections as a security measure. It is assumed that sockets.io are securely proxied through Nginx, which is https secured, so the gateway app wouldn't have to worry about sockets security. That's why that check is there.

In any case I think what you are doing in sms_gateway.js could and should be included in gateway.js as an extension. Maybe I don't fully get the picture.
SMS is pretty crude and unreliable. I don't use it much anymore myself. Email is better :)

HeneryH

As to the question of Why...

If you can suggest any other way for me to turn an outlet on/off based on a Mot reading I am all ears.

Barring a better idea, I am
* Taking Mot readings and sending them to IFTTT,
* then using IFTTT to send an SMS to a Twilio number
* Twilio then sends a POST message to my sms_gateway.js
*  which gets interpreted by the sms_gateway server to inject a command to gateway.js.

Very round about, but I just need to turn a switch off or on based on a Mot reading.

Felix

What exactly is the "Mot"? Some RFM device on your RF network? Or some internet device?
Btw you mean Mote right?

And what is that reading?

HeneryH

This is getting crazy with so many different threads.  Sorry.

WaterTempMote takes water temperature readings.
...based on that...
SwitchMote turns on/off de-icer.


I used a sample from spark about doing SMS interface to GarateMote.


Felix

I would simply write a polling event, for your WaterMote.
It should check the last value reported, based on that, send an ON/OFF message to the SwitchMote.
You would want to add some "hysteresis" (ie fail safe) to this on/off mechanism.
Sorry I don't have a better example but see this built in example, which triggers a SwitchMote to ON when there is MOTION:

motionLightON23 : { label:'Motion: SM23 ON!', icon:'action', descr:'Turn SwitchMote:23 ON when MOTION is detected', serverExecute:function(node) { if (node.metrics['M'] && node.metrics['M'].value == 'MOTION' && (Date.now() - new Date(node.metrics['M'].updated).getTime() < 2000)) { sendMessageToNode({nodeId:23, action:'MOT:1'}); }; } },


The SwitchMote automatically has an OFF timer. In your case you can do the same, or write the OFF logic in the event based on temperature.

HeneryH

Thanks for the alternative idea Felix.

I wrote the following custom metric file for the water thermometer:
//you will have to import any used functions from metrics.js this way:
exports.timeoutOffset = require('../metrics.js').timeoutOffset;
exports.futureDateOffset = require('../metrics.js').futureDateOffset;

exports.metrics = {
};

//example of overriding a mote
exports.motes = {
  WaterTempMote: {
    label  : 'Water Temp Thermometer',
    icon   : 'icon_weather.png',
    controls : {
    },
  },
}

//example of overriding an event
exports.events = {
    de_icerON : { label:'De-Icer: SM101 ON!', icon:'action', descr:'Turn SwitchMote:101 ON when temp goes below x.', serverExecute:function(node) { if (node.metrics['F'] && node.metrics['F'].value < 60 && (Date.now() - new Date(node.metrics['F'].updated).getTime() < 2000)) { sendMessageToNode({nodeId:101, action:'BTN0:1'}); }; } },

    de_icerOFF : { label:'De-Icer: SM101 OFF!', icon:'action', descr:'Turn SwitchMote:101 OFF when temp goes above x.', serverExecute:function(node) { if (node.metrics['F'] && node.metrics['F'].value > 62 && (Date.now() - new Date(node.metrics['F'].updated).getTime() < 2000)) { sendMessageToNode({nodeId:101, action:'BTN0:0)'}); }; } },
};

//example of defining a property to use anywhere in the app/events or in other custom functions
exports.ONEDAYHOURS = 24;

//example of defining a general purpose function to use in the app/events or in other custom functions
exports.secondsInOneDay = function() {
  var result = exports.ONEDAYHOURS * 3600;
  return result;
};



It got the following log messages:

When I dropped the thermometer in the ice water, the temperature dropped and I got the following logs
Quote[11-19-18_21:09:54.798] [LOG]    >: [40] BAT:4.86v F:39.20 H:0.00 P:0.00   [RSSI:-52][ACK-sent]
[11-19-18_21:09:54.817] [LOG]    post: /home/pi/gateway/data/db/0040_V.bin[1542679794,4.86]
[11-19-18_21:09:54.828] [LOG]    post: /home/pi/gateway/data/db/0040_F.bin[1542679794,39.2]
[11-19-18_21:09:54.838] [LOG]    post: /home/pi/gateway/data/db/0040_H.bin[1542679794,0]
[11-19-18_21:09:54.850] [LOG]    post: /home/pi/gateway/data/db/0040_RSSI.bin[1542679794,-52]
[11-19-18_21:09:54.875] [LOG]    NODEACTION: {"nodeId":101,"action":"BTN0:1"}
[11-19-18_21:09:54.898] [LOG]       [40] DB-Updates:1
[11-19-18_21:09:54.940] [LOG]    >: GTWCMD:10

The outlet didn't turn on though.

If I use the gateway portal to turn it on, it does and I get the following log.  I note there are a few differences in the logged output
Quote
[11-19-18_21:10:49.330] [LOG]    NODEACTION: {"nodeId":101,"action":"BTN0:1"}
[11-19-18_21:10:49.336] [LOG]    CONTROLCLICK:{"nodeId":101,"action":"BTN0:1","nodeType":"SwitchMote","controlKey":"B0","stateKey":"0"}
[11-19-18_21:10:49.349] [LOG]    >: GTWCMD:101:BTN0:1
[11-19-18_21:10:49.372] [LOG]    >: ACK:OK
[11-19-18_21:10:49.397] [LOG]    >: [101] BTN0:1   [RSSI:-37][ACK-sent]
[11-19-18_21:10:49.419] [LOG]    post: /home/pi/gateway/data/db/0101_RSSI.bin[1542679849,-37]
[11-19-18_21:10:49.454] [LOG]       [101] DB-Updates:1

Does this give any obvious ideas to the error of my attempt?

HeneryH

Hmmm, this time it seems to have turned on.   I put the WaterThermometerMote outside to test the solar supercap performance and when I can back to the SwitchMote later, the outlet was ON.  I'll do some more testing of the getting colder and getting warmer scenarios.

Felix

Ok but what is "GTWCMD:"  ???

You probably want "BTN1:1" if you're using the default SwitchMote sketch, which has the main relay on button #1.