Log router status to a Google Spreadsheet via IFTTT

Log router status to a Google Spreadsheet via IFTTT


We are going to create a package that will allow us to log router status data to a Google Spreadsheet.

Add new entry to GUI

We are going a add a new entry to the web interface to configure our application. Execute following commands (remember that lines preceded by // are comments and should not be typed):
// Create the folder luci-ifttt
mkdir ~/code/barrier_breaker/feeds/luci/applications/luci-ifttt
// Go to folder luci-ifttt
cd ~/code/barrier_breaker/feeds/luci/applications/luci-ifttt
// Create folder structure luasrc/controller
mkdir -p luasrc/controller
// Create file ifttt.lua
touch luasrc/controller/ifttt.lua
Edit the file ifttt.lua so it looks like this:
module ("luci.controller.ifttt", package.seeall)

function index()
    if not nixio.fs.access("/etc/config/ifttt") then
        return
    end

    local page
    page = entry({"admin", "services", "ifttt"}, cbi("ifttt"), _("IFTTT"), 0)
    page.dependent = true
end
The new web entry will only be displayed if there is a file /etc/config/ifttt in the file system to save the user settings. The entry will be added to Services tab and will be displayed in first position. Let's add the content of the web form so the user can enter the needed settings:
// Create folder structure luasrc/model/cbi
mkdir luasrc/model/cbi
// Create file ifttt.lua
touch luasrc/model/cbi/ifttt.lua
This new file should have following content:
// This is an array containing all the options the user can configure
m = Map("ifttt", translate("IFTTT"))

// A default name given to the section as it will be shown in the web interface
s = m:section(TypedSection, "ifttt", translate("Settings for IFTTT"))
s.anonymous = true

// The IFTTT key the user will need to provided. This is a simple text box in the GUI
key = s:option(Value, "key", "Maker Key", "Enter your key here")
// The IFTTT event/trigger name. This is another text box
trigger = s:option(Value, "trigger", "Trigger name", "Enter the trigger you want to fire here")

// The frequency that configures how often the data has to be pushed.
// This is a dropdown
frequency = s:option(ListValue, "frequency", "Frequency")
frequency:value("15", "15s")
frequency:value("30", "30s")
frequency:value("60", "1m")

return m
As we have already mentioned, the web entry will be only displayed if there is a config file to save the settings. Let's create it:
mkdir -p root/etc/config
touch root/etc/config/ifttt
Edit this file as follows (by default, the configuration will be empty):
config ifttt
Create the Makefile:
touch Makefile
And add following lines:
PO = ifttt

include ../../build/config.mk
include ../../build/module.mk
OpenWrt does not know about this new package yet. It is needed to edit file ~/code/barrier_breaker/feeds/luci/contrib/package/luci-addons/Makefile and following line:
// Look for 'wshaper' and add this line below it
$(eval $(call application,ifttt,LuCi IFTTT application,ifttt))
By adding ifttt at the end of the line we are just defining that this package depends on another package called ifttt. It makes sense that the front-end can only be installed if the back-end is already installed. To compile the package run:
make menuconfig
// Select the package under LuCi > Applications and then save and exit

// Compile the package
make -j 3
You can copy the package from your virtual machine to the router by executing:
scp bin/ramips/packages/luci/luci-app-ifttt_0.12+git-16.038.38474-0d510b2-1_ramips_24kec.ipk root@192.168.1.1:/tmp
You may try to install the package on the router, but it will not work as it has one dependency (the package ifttt).
luci-ifttt
luci-ifttt.tar.gz
Version: 1 – File size: 992 B

Add ifttt package

This is the package that runs in the back-end and actually does something. It reads the settings entered by the user in the GUI and then will pushed the data to a Google Spreadsheet. Execute following commands:
// Go to folder ~/code/apps
cd ~/code/apps
// Duplicate the helloworld folder
cp -R helloworld/ ifttt
// Go to folder ifttt
cd ifttt
Edit file main.c so it looks like this:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(void)
{
    // Definition of variables
    FILE *fp;
    char key[50];
    char trigger[20];
    char imei[20];
    char serial[50];
    char ip[25];
    char frequency[10];
    char command[300];
    int freq;

    //Read the key submitted by the user
    fp = popen("uci get ifttt.@ifttt[0].key", "r");
    while (fgets(key, sizeof(key), fp) != NULL)
    {
        printf("Key is %s\n", key);
    }
    pclose(fp);
    key[strlen(key)-1] = 0;
 
    //Read the trigger submitted by the user
    fp = popen("uci get ifttt.@ifttt[0].trigger", "r");
    while (fgets(trigger, sizeof(trigger), fp) != NULL)
    {
        printf("trigger is %s\n", trigger);
    }
    pclose(fp);
    trigger[strlen(trigger)-1] = 0;

    //Read frequency
    fp = popen("uci get ifttt.@ifttt[0].frequency", "r");
    while (fgets(frequency, sizeof(frequency), fp) != NULL)
    {
        printf("frequency is %s\n", frequency);
    }
    pclose(fp);
    frequency[strlen(frequency)-1] = 0;
    // Convert the string to an integer value
    freq = atoi(frequency);

    //Read IMEI
    fp = popen("cat /tmp/sysinfo/imei", "r");
    while (fgets(imei, sizeof(imei), fp) != NULL)
    {
        printf("IMEI is %s\n", imei);
    }
    pclose(fp);
    imei[strlen(imei)-1] = 0;

    //Read serial number
    fp = popen("cat /tmp/sysinfo/prodid", "r");
    while (fgets(serial, sizeof(serial), fp) != NULL)
    {
        printf("Serial is %s\n", serial);
    }
    pclose(fp);
    serial[strlen(serial)-1] = 0;

    // Make this loop run forever (until user exits)
    while (1)
    {
        //Get public IP
        system("curl -s checkip.dyndns.org | sed -e 's/.*Current IP Address: //' -e 's/<.*$//' > /tmp/public_ip");
        // Sleep for 5s to make sure the previous request is completed in time
        sleep(5);
        // Read the public IP address stored in the previous line
        fp = popen("cat /tmp/public_ip", "r");
        while (fgets(ip, sizeof(ip), fp) != NULL)
        {
            printf("Public IP is %s\n", ip);
        }
        fclose(fp);
        ip[strlen(ip)-1] = 0;

        // Create the command to POST the data to IFTTT
        strcpy(command, "curl -X POST -H \"Content-Type: application/json\" -d '{\"value1\":\"");
        strcat(command, imei);
        strcat(command, "\", \"value2\":\"");
        strcat(command, serial);
        strcat(command, "\", \"value3\":\"");
        strcat(command, ip);
        strcat(command, "\"}' http://maker.ifttt.com/trigger/");
        strcat(command, trigger);
        strcat(command, "/with/key/");
        strcat(command, key);
        system(command);
        // Sleep for the amount of time defined by the user so the data is pushed periodically
        sleep(freq);
    } 
    return 0;
}
Edit the Makefile:
.SUFFIXES: .tar.gz .c
PKG_RELEASE:=1
PKG_VERSION:=0
TARGET = ifttt
SOURCES = main.c
OBJECTS = $(SOURCES:.c=.o)
LDFLAGS += -lpthread
OPENPATH=~/code/barrier_breaker/dl/$(TARGET).tar.gz

$(TARGET): $(OBJECTS)
    $(CC) $(CFLAGS) $(LIBS) $(OBJECTS) -o $(TARGET) $(LDFLAGS)

copy:
    mkdir -p ./$(TARGET)-$(PKG_VERSION).$(PKG_RELEASE)
    cp -rf $(SOURCES) Makefile ./$(TARGET)-$(PKG_VERSION).$(PKG_RELEASE)
    tar -cz -f $(TARGET).tar.gz ./$(TARGET)-$(PKG_VERSION).$(PKG_RELEASE)
    cp ./$(TARGET).tar.gz ~/code/barrier_breaker/dl/
    rm -rf *.tar* $(TARGET) $(TARGET)-$(PKG_VERSION).$(PKG_RELEASE) *.o *~

all: $(TARGET)
# Objects
%.o: %.c
    $(CC) -c $(CFLAGS) $< -o $@
clean:
    rm -rf *.tar* $(TARGET) $(TARGET)-$(PKG_VERSION).$(PKG_RELEASE) *.o *~ $(OPENPATH)
Make sure your code compiles and copy it:
make
make clean
make copy
Create the package inside the OpenWrt hierarchy:
cd ~/code/barrier_breaker/feeds/packages/utils/
cp -R helloworld/ ifttt
cd ifttt
Edit the Makefile:
include $(TOPDIR)/rules.mk

PKG_NAME:=ifttt
PKG_VERSION:=0
PKG_RELEASE:=1

PKG_SOURCE:=$(PKG_NAME).tar.gz
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION).$(PKG_RELEASE)

include $(INCLUDE_DIR)/package.mk

define Package/$(PKG_NAME)
    SECTION:=utils
    CATEGORY:=Utilities
    DEPENDS:=+libpthread
    TITLE:=IFTTT Logger
endef

define Package/$(PKG_NAME)/description
    Logs router status to IFTTT.
endef

define Build/Configure
endef

define Build/Compile
    $(MAKE) -C $(PKG_BUILD_DIR) $(TARGET_CONFIGURE_OPTS)
endef

define Package/$(PKG_NAME)/install
    $(INSTALL_DIR) $(1)/bin
    $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/bin/
endef

$(eval $(call BuildPackage,ifttt))
Compile the .ipk package:
cd ~/code/barrier_breaker
./scripts/feeds update -a && ./scripts/feeds install -a
make menuconfig
// Select package ifttt and then save and exit
make package/ifttt/compile
Copy the package to your router:
scp bin/ramips/packages/packages/ifttt_0-1_ramips_24kec.ipk root@192.168.1.1:/tmp
Install both the front and back-end applications:
ssh root@192.168.1.1
cd /tmp
opkg install ifttt_0-1_ramips_24kec.ipk
opkg install luci-app-ifttt_0.12\+git-16.038.38474-0d510b2-1_ramips_24kec.ipk
ifttt
ifttt.tar.gz
Version: 1 – File size: 2 KB
Reboot your router from the web interface.

Create an IFTTT applet

Sign up for an account at ifttt.com and create a new applet from  https://ifttt.com/create:
  1. Click on this:
  2. Choose Webhooks as the service to be used:
  3. Click on Receive a web request.
  4. Enter an Event name:
  5. Click on that:
  6. Choose Google Sheets:
  7. Click on Add row to a spreadsheet.
  8. Customize the spreadsheet name, row format and folder path in Google Drive and Create action:
  9. Click on Finish.

Configure the IFTTT logger

Go to Services > IFTTT and configure enter the settings needed:
  • Key: you can check your IFTTT key at https://ifttt.com/maker_webhooks.
  • Trigger: it is the event name entered on step 4 above.
  • Frequency: select one of the three values available.
  • Click on Save & Apply to save your settings.
SSH into the router and run the ifttt application:
ssh root@192.168.1.1
ifttt
If everything  went ok you should see the settings entered by the user and a confirmation message that your event was triggered successfully. You can check on Google Drive for the new spreadsheet document and the data that is being uploaded by the router:  



[Originally Published On: 09/23/2019 11:22 AM]