Tuesday, April 25, 2017

tweet.sh on LinkIt Smart 7688 Duo (OpenWrt)

Temboo-less tweeting from the shell

LinkIt 7688 Duo is a cheaper ($15.9 vs $74.95) and breadboardable version of Arduino Yun. Arduino Yun comes preloaded with Temboo whereas LinkIt does not have that preloaded. Temboo is a great go between service that allows your IoT project to talk to existing services like google drive, twitter or dropbox - but to do anything long term and meaningful with it, you have to upgrade from a free temboo plan to a paid plan - Arduino Yun is already expensive and this makes it even moire expensive. I used Arduino Yun and Temboo to make a shimmering lamp that reacts to tweets from your sweetheart - But now it was time to move on to better yet cheaper builds.

A Raspberry Pi running Node Red can achieve a lot but here I want to focus on LinkIt because I am using it as a part of a larger "art" project. Since LinkIt has an AVR microcontroller (Arduino programmable over WiFi and Arduino Bridge), it allows for greater flexibility in interfacing to sensors and modules via the microcontroller. Also, until someone (or me) ports Node Red to OpenWrt platforms, I would prefer to use bash scripts and Arduino code to get my bidding done.

So one of the first things on my agenda was to figure out a Temboo less way of fetching tweets. What is outlined below is how I got https://github.com/piroor/tweet.sh (which is a bash script to fetch tweets)to work on OpenWrt - more specifically LinkIt 7688 Duo. For this, we wont be writing any Arduino code since the Microcontroller does not come into play (yet). But what we will be doing is playing around with bash scripts and cross compiling 2 packages for OpenWrt.

My LinkIt 7688 Duo as a part of a larger project.
The LinkIt is the one in the middle. The one on a bottom is a 5V powersupply.
And the one on top is a dimmer circuit - similar to the one I used in my twitter lamp project

Step 1 - Cross compiling packages required by tweet.sh

Since tweet.sh is just a bash script, it requires certain packages to exist on your system. They are curl, jq, nkf, openssl. Of these openssl and curl can be installed on your LinkIt since they are a part of the OpenWrt repositories. But jq and nkf - these you will have to cross compile on a Linux PC and transfer them to LinkIt.

Here are the steps to make sure you have all the packages required by tweet.sh on your LinkIt:


  1. Connect your LinkIt to your home's WiFi network - check this
  2. Figure out your LinkIt's IP address - there are many ways to do this:
  3. Using my router's page to figure out the IP addresses of my 2 LinkIts connected to my home network.
    The MAC addresses of LinkIt begin with 9e:65:f9
    (Yes I have OpenWrt installed on my home router as well)
    Using Arduino IDE to figure out the IP addresses of LinkIt
    1. You may need to log on to your WiFi Router's page from your PC and look at the list of devices and IP addresses.
    2. You can install Arduino on your PC, add support for LinkIt 7688 Duo and then wait for a few moments till Arduino automatically discovers the LinkIt. Then you can look under Tools>Ports
  4. Use PuTTY to login to your LinkIt 7688 Duo. Login will be "root" and password would be whatever you set during the getting started stage.
  5. Lets install the basic packages that are required and available - execute the following commands on LinkIt over PuTTY:

    opkg update

    opkg install ip curl openssl bash nano grep getopt bc ca-certificates 
  6. We still need to install nkf and jq. For that, we will need to use a Linux computer - preferable one running Ubuntu and perform the following steps (on your Linux PC not LinkIt):
    1. Download OpenWRT SDK for Linux from here onto your x64 Ubuntu Laptop. (I used Ubuntu 15.10 x64 on a VirtualBox Virtual Machine - I used a virtualbox image from http://www.osboxes.org/)
    2. Extract the folder to your home folder:
      tar -xvf OpenWrt-SDK-ramips-mt7688_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64.tar
    3. Install some required build tools on your Ubuntu PC:
      sudo apt-get install autoconf build-essential
    4. Set the environment variables:

      export PATH=~/OpenWrt-SDK-ramips-mt7688_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin:$PATH

      export STAGING_DIR=~/OpenWrt-SDK-ramips-mt7688_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64/staging_dir
    5. Change to ~/OpenWrt-SDK-ramips-mt7688_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64.tar/package :
      cd ~/OpenWrt-SDK-ramips-mt7688_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64.tar/package
    6. Create two folders here:
      mkdir jq
      mkdir nkf
    7. Create the makefile for jq and place it in the jq directory that you just created. (Appended Below):
      gedit jq/Makefile
    8. Create the makefile for nkf and place it in the nkf directory that you just created (Appended Below)
      gedit nkf/Makefile
    9. Go back to ~/OpenWrt-SDK-ramips-mt7688_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64:
      cd ~/OpenWrt-SDK-ramips-mt7688_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64
    10. And issue the make command:
      make
    11. cd to the ourput directory:
      cd ~/OpenWrt-SDK-ramips-mt7688_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-x86_64/bin/ramips/packages/base
    12. You will find the two .ipk files:
      jq_1.5_ramips_24kec.ipk
      nkf_2.1.4-1_ramips_24kec.ipk
    13. Copy these two ipk files to your LinkIt 7688 duo. you can do this in many ways but the best way is to use scp protocol. In my case I simply copied the files from my Ubuntu Virtual Machine to my Windows machine and used WinSCP (Make sure file protocol is set to SCP) to login into my LinkIt and copied the .ipk files to the /root folder there.
    14. Issue the following commands to install jq and nkf on your LinkIt (Issue commands over PuTTY while in /root directory):
      opkg install jq_1.5_ramips_24kec.ipk
      opkg install nkf_2.1.4-1_ramips_24kec.ipk
    15. And you are done with installing the required packages
Here are the Makefiles for cross compiling jq and nkf

Makefile for nkf:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
include $(TOPDIR)/rules.mk

PKG_NAME:=nkf
PKG_VERSION:=2.1.4
PKG_RELEASE:=1

PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE:=$(PKG_SOURCE_SUBDIR).tar.gz
PKG_SOURCE_URL:=http://dl.osdn.jp/nkf/64158/
PKG_MD5SUM:=dbce0a2131cd4e30f73cbfdcc57c06ec

PKG_BUILD_PARALLEL:=1
PKG_INSTALL:=1
PKG_USE_MIPS16:=0

PKG_LICENSE:=MIT
PKG_MAINTAINER:=Yoshio HANAWA <for-openwrt@hnw.jp>

include $(INCLUDE_DIR)/package.mk

define Package/nkf
  SECTION:=utils
  CATEGORY:=Utilities
  TITLE:=Network Kanji code conversion Filter (NKF)
  URL:=https://osdn.jp/projects/nkf/
endef

define Package/nkf/description
  Network Kanji code conversion Filter (NKF)
endef

MAKE_INSTALL_FLAGS += \
  prefix="$(PKG_INSTALL_DIR)" \
  MKDIR="mkdir -p"

define Package/nkf/install
 $(INSTALL_DIR) $(1)/usr/bin
 $(INSTALL_BIN) $(PKG_INSTALL_DIR)/bin/nkf $(1)/usr/bin/
endef

$(eval $(call BuildPackage,nkf))

Makefile for jq:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#jq is written in C and has no runtime dependencies, so it should be possible to build it for nearly any platform. Prebuilt binaries are available for Linux, OS X and Windows.
#The binaries should just run, but on OS X and Linux you may need to make them executable first using chmod +x jq.
#jq is licensed under the MIT license. For all of the gory details, read the file COPYING in the source distribution.

include $(TOPDIR)/rules.mk

PKG_NAME:=jq
PKG_VERSION:=1.5
PKG_RELEASE:=

PKG_SOURCE_URL:=https://github.com/lithiumhead/jq
PKG_SOURCE_PROTO:=git
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE_VERSION:=b3078a3b1c1b3285926151e0e3af886877e7395d
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz

PKG_FIXUP:=autoreconf -i
PKG_INSTALL:=1

include $(INCLUDE_DIR)/package.mk

define Package/jq
  SECTION:=Utilities
  CATEGORY:=Utilities
  DEPENDS:=
  TITLE:=jq json interface
  URL:=
endef

define Build/Compile
 $(MAKE) -C $(PKG_BUILD_DIR) CFLAGS=-msoft-float
endef

define Package/jq/install
 $(INSTALL_DIR) $(1)/usr/bin
 $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/jq $(1)/usr/bin/
endef

$(eval $(call BuildPackage,jq))

Step 2 - Cross compiling packages required by tweet.sh

Next we need to get tweet.sh onto LinkIt and configure it.
  1. Visit https://github.com/lithiumhead/tweet.sh download tweet.sh and tweet.client.key to your PC and transfer it to your LinkIt using WinSCP. You can also download the two files directly to your LinkIt by issuing 2 commands over PuTTY:
    curl -O https://raw.githubusercontent.com/lithiumhead/tweet.sh/master/tweet.sh
    curl -O https://raw.githubusercontent.com/lithiumhead/tweet.sh/master/tweet.client.key
  2. Mark tweet.sh as executable:
    chmod +x tweet.sh
  3. Now we need to configure the keys and add them to tweet.client.key on LinkIt. Visit twitter.com and login to your twitter account.
  4. Next open a new tab in the same browser and visit https://apps.twitter.com/
  5. Click on "Create New Apps"
  6. Enter something in Name, Description and Website
  7. Accept the Developer Agreement and click "Create your Twitter Application"
  8. Now click on your newly created application and click on "Keys and Access Token"
  9. Open tweet.client.key over WinSCP and copy and past key from the webpage to tweet.client.key
    1. Enter your twitter handle next to MY_SCREEN_NAME=
    2. Enter "en" next to MY_LANGUAGE=
    3. Copy the string mentioned next to Consumer Key (API Key) to CONSUMER_KEY=
    4. Copy the string next to Consumer Secret (API Secret) to CONSUMER_SECRET=
    5. Copy Access Token to ACCESS_TOKEN=
    6. Copy Access Token Secret to ACCESS_TOKEN_SECRET=
    7. Click save
Editing tweet.client.key
The original tweet.sh is published at https://github.com/piroor/tweet.sh but I had to fork it and make some modification to it so that it would run on OpenWrt. I have forked it at https://github.com/lithiumhead/tweet.sh and that's what we have used. (Modifications involved creating symbolic links to stdin and stdout in proc file system - these are lacking by default in OpenWrt)

Finally everything is set and we can test our tweet.sh setup by fetching the latest tweet from - say - elonmusk, piping it through jq and printing only the unique tweet id and the text of the tweet itself:

./tweet.sh search -q "from:elonmusk" -c 1 | jq '.statuses[0].id, .statuses[0].text'


tweet.sh running in a PuTTY window with Twitter open in Google Chrome


0 comments:

Post a Comment