IMrek – Android group chat app using MQTT

Apr 29, 2012 by

IMrek was a project for my Android App Development class. It was developed start to finish in about a month and a half in my free time.

IMrek is a simple group chat app, similar to IRC’s channels. The MQTT protocol was perfect for this because it is very lightweight, and therefore easy on battery life and still comparatively fast on slower mobile networks.

Here are some screenshots of the app in action:

Features include:

  • Registration/Login via PHP (before MQTT login)
  • Channel list
  • Join/Create a Channel
  • Send/Receive messages on channels
  • Message history
  • New message notifications
  • Persistent background service

IMrek’s background service handles the MQTT connection, and tries to reconnect automatically if the connection is lost. It also attempts to restart itself if it crashes or is killed by the Android OS for any reason.

Another pretty awesome feature (in my opinion) is that you can left and right swipe between channels, without having to go back to the conversation list. This uses the same swipe effect that swiping between images in the image gallery does. It accomplishes this by using activity fragments for each channel.

The code for IMrek is open source, and you can get a copy from Github.

I recently presented IMrek, along with an Arduino MQTT client I made, at the Johnson & Wales 2012 Tech Exhibit. The Arduino client was the result of my recent experimentation of reading IR remotes with my Arduino board. I thought an Arduino MQTT client that used an LCD and infrared keyboard would be awesome, and I just couldn’t put off the thought.

The Arduino client is rather simplistic:

  1. I use this Arduino HTTPClient library to authenticate with IMrek’s PHP server-side
  2. On Github, I forked Nicholas O’Leary’s Arduino MQTT client library pubsubclient and implemented user/pass authentication, the result of which I use for the authenticated MQTT connection.
  3. I read in IR signals using the IRRemote library, and map them to the keyboard keys.

The LCD display shows an input line (with the message you’re typing), a sent/received count, and the last message the client received from the server. Currently, it it hard-coded to connect to one MQTT topic, but that can easily be changed (Future updates!).

If you’d like to try it out yourself, you can get the code on Github.

As far as the physical circuit goes, the mass of it is just the LCD hookup (it’s a 4×20 LiquidCrystal display), and then an IR receiver connected to pin 32, and a blue status LED connected to pin 30 to show when a signal is received.

I’m running this on my ATMega2560 with the R3 version of the ethernet shield:

I also have some more pictures from my presentation at the Tech Exhibit (and hopefully video soon!):

And my brief presentation, if anyone is interested:

 

Update: IMrek now uses Eclipse Paho for its MQTT client library.

read more

Related Posts

Share This

yunochrome.com

Nov 30, 2011 by

Just created a small joke site, yunochrome.com. If you visit the site using Google Chrome, you get a reassuring message. Visit with any other browser, though, and you are presented with a message urging you to get chrome.

Why? Because, simply, Google Chrome is awesome.

read more

Related Posts

Tags

Share This

Compiling pypcap for python 2.x for OS X

Nov 2, 2011 by

Just a quick post about a problem I encountered when trying to install pypcap for Python 2.7 on OS X Lion. I’m not sure if this error is present on other systems, or for python 3.x (versions pervious to 2.x have binary installers), but the errors from the build output were something like this:

llvm-gcc-4.2 -fno-strict-aliasing -fno-common -dynamic -g -Os -pipe -fno-common -fno-strict-aliasing -fwrapv -mno-fused-madd -DENABLE_DTRACE -DMACOSX -DNDEBUG -Wall -Wstrict-prototypes -Wshorten-64-to-32 -DNDEBUG -g -fwrapv -Os -Wall -Wstrict-prototypes -DENABLE_DTRACE -arch i386 -arch x86_64 -pipe -I/usr/include -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c pcap_ex.c -o build/temp.macosx-10.7-intel-2.7/pcap_ex.o
pcap_ex.c: In function ‘pcap_ex_fileno’:
pcap_ex.c:165: error: dereferencing pointer to incomplete type
pcap_ex.c: In function ‘pcap_ex_next’:
pcap_ex.c:253: error: dereferencing pointer to incomplete type
pcap_ex.c: In function ‘pcap_ex_fileno’:
pcap_ex.c:165: error: dereferencing pointer to incomplete type
pcap_ex.c: In function ‘pcap_ex_next’:
pcap_ex.c:253: error: dereferencing pointer to incomplete type

I found a fix for this here, which involves patching pcap_ex.c and adding the following line to the top of the file:

#define HAVE_PCAP_FILE

The comment in the above link suggests that the fix also works on Ubuntu, but also for Python 2.7.

So, I don’t have much of an explanation, but hopefully this helps someone.

read more

Related Posts

Tags

Share This

Love Visor/TotalTerminal but miss Window Groups? No Problem!

Oct 27, 2011 by

Today I was faced with a grim reality when I restarted my Macbook Pro for some updates: I was unable to open my saved window group into TotalTerminal. What a pain!

For those of you who are unfamiliar, Visor TotalTerminal(the name was changed. “Visor” was cooler) is an awesome mac application that lets your Terminal function as a system-wide slide-down HUD window. Pretty cool. However, it officially doesn’t support window groups; luckily, I have a workaround that is simple, efficient, and universal.

Applescript does the job perfectly – it comes installed on every mac, and can programmatically issue all the commands we need to our Visored Terminal with minimum hassle.

To go about this, I define a variable detailing the tabs I want in my window group:

set tTitles to {"Django Server", "Python Shell", "Django Shell", "Git Shell"}

This serves as a list of names for the tabs, and the number of tabs to create. The above is an example of one of my window groups I use.

Next, to create the tabs, we need to make the Terminal window active. However, we can’t simply activate the Terminal window, because that breaks TotalTerminal. Instead, we do:

tell application "System Events"
tell process "Finder" to keystroke "`" using command down
repeat with i from 1 to ((count tTitles) - 1)
tell process "Terminal" to keystroke "t" using command down
end repeat
end tell

We tell to “System Events” so we can access processes
We invoke our Visored Terminal via the hotkey (change ‘keystroke “`”‘ to reflect yours)
Create X number of tabs by passing new tab keystrokes, where X is the number of tabs in our list of tab titles
At this point, the new tabs are created, but they are not named. That’s the next part. Now we do:

tell application "Terminal"
set tTabs to every tab in window 1
repeat with i from 1 to (count tTabs)
set tTab to item i of tTabs
set tTitle to item i of tTitles
activate tTab
do script with command "PS1=\"\\[\33]0;`(echo \"" & tTitle & "\")`7\\]$PS1\";clear" in tab i of window 1
end repeat
end tell

We assume there is only one window (Because there can only be one visored-window at a time)
Set the variable tTabs to every tab in TotalTerminal (the ones we created)
And for each tab, we:
Get the title from our list (iTitles)
Make the tab active
Rename the tab using the PS1 environment variable
Run “clear” to clear the terminal tab
Why set PS1? because doing “set custom title of tab i to whatever” sets all the tabs to that title, for some reason. I’m not sure if this is exclusive to TotalTerminal, but I couldn’t find a way around it.

Next, to sum up, just close TotalTerminal:

tell application "System Events"
tell process "Finder" to keystroke "`" using command down
end tell

And we’re done. Simple. The final result looks something like the following:

set tTitles to {"Django Server", "Python Shell", "Django Shell", "Git Shell"}
[/code

1
tell application "System Events"
tell process "Finder" to keystroke "`" using command down
repeat with i from 1 to ((count tTitles) - 1)
tell process "Terminal" to keystroke "t" using command down
end repeat
end tell
tell application "Terminal"
set tTabs to every tab in window 1
repeat with i from 1 to (count tTabs)
set tTab to item i of tTabs
set tTitle to item i of tTitles
activate tTab
do script with command "PS1=\"\\[\33]0;`(echo \"" & tTitle & "\")`7\\]$PS1\";clear" in tab i of window 1
end repeat
end tell
tell application "System Events"
tell process "Finder" to keystroke "`" using command down
end tell

So far, I have found only one issue, which is that tab names sometimes refuse to update after being changed, seemingly at random. Once the tab is clicked, the name updates. It seems a steep price to pay for having the convenience of my window groups back.

Keep in mind that you are not limited to simply creating and renaming tabs. It is just as easy to execute commands automatically after they are created, enabling a large number of customizations. A simple example is setting the initial working directory, which is a feature of window groups that can be useful.

To do this, we could define a new list:

set tDirs to {"~/folder1/", "/Users/me/", "~/this/", "~/this/that/"}

And then use it later, in our second block of code, something like this:

tell application "Terminal"
set tTabs to every tab in window 1
repeat with i from 1 to (count tTabs)
set tTab to item i of tTabs
set tTitle to item i of tTitles
activate tTab
do script with command "cd\"" & (item i of tDirs) & "\"" in tab i of window 1
do script with command "PS1=\"\\[\33]0;`(echo \"" & tTitle & "\")`7\\]$PS1\";clear" in tab i of window 1
end repeat
end tell

….The possibilities really are endless, really. It’s pretty exciting.

read more

Related Posts

Tags

Share This