Log router status to a Google Spreadsheet via IFTTT

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.