Sunday, December 1, 2013

Sony Smartwatch 2 Programming

Some tips:
- the documentation seems to be, well, sparse. The most helpful thing I've found was code samples. They released five with the SDK (Sample{Control, Widget, AdvancedControl, Sensor, Notification}Extension) and two more here (EightPuzzleExtension and OSS_MusicExtension). Load them up into Eclipse as Android projects, they mostly work out of the box.
- well, mostly. For EightPuzzleExtension, I had to add <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> to the Android Manifest.
- also useful was Xiang "Anthony" Chen's HelloWatch post. All the example apps have 4 classes, and Anthony explains them better than I can. Almost all of my code went in the Extension app.

Here's the app I've been working on: MorseWatch. Mostly just takes in touch events. Also, I made a HelloSmartwatch app that uses accelerometers.

Maybe more details later. In the meantime, better to get some info and helpful links out there as soon as possible.

Excursions in rooting my Nexus 4

Man, I never really wanted to dig into phone rooting, but I recently went to do a Portable Wi-fi Hotspot and found that T-Mobile now blocks all data when I tether through my phone. (which is insane. why does T-Mobile care whether I'm using my phone or computer? I'm not using a ton of data. but anyway.)

I found this post, which explains how to edit one sqlite database to allow tethering again.

Unfortunately, it's in /data/data/..., which is only editable (or even viewable) if you have root access. (this is I think the same as root on mac/linux, which is roughly the ability to "sudo".) For some reason, Android makes this difficult.

Luckily, xda-developers to the rescue.
Nexus 4 Rooting Guide.
Backing up your phone before you root it.

How'd it go? Pretty smoothly. Wiped my phone, but the two-part backup in the link above (both the "adb pull" and the "adb backup" part) meant I didn't lose much. Had to reconfigure a couple minor things, not bad. And now I can tether!

The major steps, in my mind, are:
- back up your stuff
- unlock the bootloader (this is when your phone gets wiped)
- flash (install) the custom recovery
- install the SU app or something? a little unclear on this step, but it involves installing SuperSU.
- restore your data

A couple of gotchas:
- as usual when reinstalling everything on your phone, if you use two-factor authentication (as you should), generating some backup codes beforehand makes everything easier.
- on the "clockwork mod" site, all you need is the one in the "download recovery" column.
- don't download/install over-the-air Android updates. It breaks your root. (which is not a huge deal, but it means you have to re-flash the recovery and re-install the SU app.)

Friday, August 16, 2013

find | xargs rm, if your filenames have spaces

I have a nested file structure, with 200 subdirectories, and I want to get rid of everything that ends with "Deriv.csv" (but keep all other files). Usually I would do this:
find . -name "*Deriv.csv"
to find all the files (find everything in the directory structure starting here (.) that has the name "anything that ends with Deriv.csv"), and then just rm them all, with the help of xargs. It would look like this:
find . -name "*Deriv.csv" | xargs rm
(this is a good pattern to know, though a little hard to wrap your head around at first; piping to xargs makes the results of your first thing be the argument to the second thing. So if it finds file1Deriv.csv, file2Deriv.csv, file3Deriv.csv, then the | xargs rm makes it do "rm file1Deriv.csv file2Deriv.csv file3Deriv.csv".)

The added difficulty comes in because some of the filenames have spaces, so the find returns something like:
file 1 Deriv.csv
file 2 Deriv.csv
and then just passing that to xargs rm makes it run:
rm file 1 Deriv.csv file 2 Deriv.csv
which of course makes it complain that "file" is not found, "1" is not found, "Deriv.csv" is not found, etc. (I'm lucky that I didn't have any stray things called "file" or "Deriv.csv" sitting around that I wanted to keep, or they would have been removed by this mistake!)

One thing I found here (thanks!) is:
find . -name "*Deriv.csv" | xargs -I{} rm {}
-I does two things:
1. separate arguments by line, not by whitespace (great!)
2. make everything after the -I be its own command that you can control however you want. In this case, we do something simple: take the argument (with the {}) and put it after an rm. But you could also do, for example:
mkdir deriv_files
find . -name "*Deriv.csv" | xargs -I{} mv {} deriv_files/
which is pretty neat. (reference)

Monday, June 24, 2013

Twitter -> LCD via python and arduino

I've got a little LCD screen. I thought it'd be neat if anyone could tweet and it'd show up on that screen. Kind of like that goofy thing at basketball games where you can send a text message somewhere and maybe it'll show up on the huge scoreboard.

Code's on github, if you're into that sort of thing.

Getting the tweets from twitter onto my computer

I created a new account called @dansoffice, and I want to get every tweet that mentions @dansoffice into my twitter program. I want it real-time, and I don't want to get rate limited for polling a lot, so I looked to their streaming APIs.

What I want is the "user stream", so I have to authenticate as @dansoffice and send a GET to:

Requests is a nice python library to make http easy. Pair it with requests_oauthlib (installed via pip; don't confuse it with requests_oauth), and the authentication is easy too. (make a Twitter app, go to the "OAuth tool", and it will tell you your access token and secret, and your consumer key and secret; use requests_oauthlib per their documentation. "consumer" = "client" in this case.)

And Requests even handles streaming requests via iter_lines... sort of. It's got a "chunk size" - a buffer that must fill up before it does anything. For some reason, this sometimes stops tweets from being read, until the next tweet comes in and clears out the buffer. Known issue.

So in my case, a terrible hack: also request that tweets are delimited by length, so the length comes in, followed by a newline, and clears the buffer; at this point, send another request (this one non-streaming, to mentions_timeline) to get the actual text of the most recent @dansoffice mention. Ugh.

Getting the tweets from my computer to the LCD

Python writes nicely to serial, via pyserial. Found my serial port's name from Arduino (tools->serial port menu). Easy enough to write to it when I get a tweet.

The LCD screen I have is this 20x4 display. I had to solder some header pins to it. Arduino has a nice LCD demo, which was easy and straightforward after I fixed my shoddy solder job. At that point, it became just a matter of chopping a string into 4 lines. (Nothing is easy in C.)


Now, as long as my little twitter monitor is running, and the Arduino is connected, tweets mentioning @dansoffice show up in real time. Now all I have to do is get a long mini-USB cable to stretch to my window. All the tweet-publicizing excitement of the NBA!

(maybe my next thing should mimic the Skinner-style pizza/t-shirt bribes and exhortations to MAKE SOME NOISE.)

Wednesday, June 19, 2013

Embedding a browser in a python application on a mac

I heard about PyQtWebkit (e.g. here). Sounds great.

First I had to get PyQt. Or maybe PyQt and Webkit, or Py and QtWebkit, or who knows. I wanted all those parts.

Tried to install it from source (e.g. from Riverbank) but that was a hopeless mess. Version 4 or 5? I don't know. I had to build SIP first, which eventually went fine. I tried to build PyQt, but had trouble because it couldn't find qmake, so I went looking for that. But then (as I often do when building things from source) I wondered if I was doing this whole thing wrong.

Tried to install PyQt using MacPorts, but either didn't find the right port or something didn't work. So I tried Homebrew (which is like MacPorts but newer; says you shouldn't run both but it's been okay for me so far):
brew install pyqt

Turns out, I guess, PyQtWebkit is included in PyQt; I just ran the code at the top of the above link, and bam! in a python Qt window.
I wonder if I could have used pip to get PyQt; looks doubtful though.

Looks like instead maybe I could have downloaded PyQtX. But I haven't tried that.

Related: Selenium, but that drives an external browser, doesn't let you put one in your own app. Followed the instructions here.