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
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
Reboot your router from the web interface.
ifttt.tar.gz
Version: 1 – File size: 2 KB
Version: 1 – File size: 2 KB
Create an IFTTT applet
Sign up for an account at ifttt.com and create a new applet from https://ifttt.com/create:- Click on this:
- Choose Webhooks as the service to be used:
- Click on Receive a web request.
- Enter an Event name:
- Click on that:
- Choose Google Sheets:
- Click on Add row to a spreadsheet.
- Customize the spreadsheet name, row format and folder path in Google Drive and Create action:
- 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 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]