Monday, October 28, 2013

Verizon Samsung Galaxy S4: Installing a Custom ROM (Hyperdrive RLS10)

(This is a continuation of my previous post: Link)

Preface: Following the problems I had updating my rooted ME7 to an MI1 build, my stubborn mind is finally convinced that OTA and root NEVER go well together. So, having said that personal disclaimer, let's jump into the custom ROM world for the S4. Currently, I'm running Hyperdrive RLS10 on my S4 ~ and I'm generally quite happy with it; but here's a little bit about how I got here, and some of the issues I've found.

Samsung's Galaxy S4 has a ton of features ~ many as a result of software, though. Even my AOSP-loving mindset has to admit that Touchwiz is a (dare I say it) good thing with this phone. But it does greatly complicate things if you want a custom ROM.

For example, you like air gestures? You know, those cool things that let you make iSheep hang their head in jealous shame? Well, you better make sure your new custom ROM has the kernel modules necessary to drive that. Same can be said for any other hardware, too... the RGB sensor, even WiFi. As with any computer, the drivers need to work; and many of these (driver and hardware) are not exactly open source.

So, how do you choose a custom ROM without losing TW? It turns out, that's not very difficult with the S4 (even the S3 - might have to try this with my wife's S3, soon). But, the list does (currently) narrow down once you factor in Verizon... and even more once you factor in your current firmware build (MDK, ME7, or MI1). I narrowed my list down to three possibilities, based on my Verizon S4 running MI1 firmware (it's a SCH-I545):
  1. Hyperdrive (http://forum.xda-developers.com/showthread.php?t=2301724)
  2. Jeally Beans (http://forum.xda-developers.com/showthread.php?t=2307357)
  3. Eclipse (http://forum.xda-developers.com/showthread.php?t=2351840)
I ended up going with Hyperdrive, because it seemed to be very well supported by the developer & community, everybody said it's stable and pretty much everything works because it's based on the stock TW stuff. I also like the included AROMA installer, which gave me the option of how much AOSP vs TW I wanted (it's an installer shell that lets you customize the ROM before it's installed).

Honestly, it was a close toss-up between Hyperdrive and Jelly Beans. The only reason I went with Hyperdrive was a couple of posts talking about how MI1 owners were happily working with it... I might yet still want to try Jelly Beans, though (possibly a future post).

Anyway, here's how I installed it:
  1. I rooted my MI1 firmware, using the "Root de la Vega" method:
  2. I then installed "Safestrap" recovery using a sideloaded APK:
  3. In Safestrap, I created a new ROM slot (it's like a partition) for my Hyperdrive installation to go in... all I did was increase the sizes a bit for system, data, and cache - per my own preference.
  4. From there, it's Hyperdrive flashing time... just install from the ROM file like you would any other (using Safestrap). I followed the instructions for "ME7" at http://forum.xda-developers.com/showthread.php?t=2301724.
    • An important note about AROMA... just customize to your own preference... only be sure to choose the "safestrap kernel" toward the end.
    • Once the ROM is installed (do NOT reboot yet), tap the 3-dot little menu icon to go back to the safestrap menu. Click through to install another ZIP, and choose the kernel modules zip file that you copied to your memory card in step 2 above.
  5. Now, you may reboot... everything should now work. Enjoy!
NOTE: The only thing I've found that doesn't work is auto-rotate. This is a common problem, and is likely due to the fact that we're using a ME7 based ROM (which Hyperdrive RLS10 is) but began with a MI1 firmware and are using MI1 kernel modules. Until Hyperdrive is based on MI1, this probably won't work? Unless we can make an easy modification to the kernel modules ZIP file... perhaps using the ME7 module, specifically, for the rotate feature?

Thursday, October 24, 2013

Verizon Samsung Galaxy S4: Problems Updating a Rooted ME7 to MI1 Firmware

Before my current Verizon Samsung Galaxy S4, I dealt with an old Motorola Droid X2 for a few years. If you don't know, it was a phone that had less than 512MB of usable RAM ~ actually, effectively less than 384MB (in other words, it lagged like a bitch). So, to squeeze as much life out of it as possible, I used the Eclipse ROM on it. I've used custom ROMs before, but that was the first time I really saw a performance improvement because of one... you know, getting rid of bloatware is always a good thing.

Fast-forward to my newer S4... with 2GB of RAM and 4 CPU cores, it hardly needs a performance improvement -- and their TouchWiz actually seemed good on this one (AOSP blasphemy?). So, for a while, I happily used stock Samsung Android (VRUAMDK) -- unrooted, even.

Then the VRUAME7 OTA came, and I immediately updated to it... something I would come to regret. That update ensured I would not be able to root for at least 2 more months until a bounty on XDA got up to a few thousand dollars and someone found an exploit (albeit, still with a locked bootloader). What can I say? After the old Moto DX2, I was giddy about ANY newer version of Android! Lesson learned: heed the warnings about accepting OTAs... do NOT do them if you're rooted!!! Period!

So, when VRUDMI1 was recently available OTA, I was a lot more hesitant to accept the update; but after several days of being nagged by it (and not finding any major issues about it, in my searches online), I finally pulled the trigger and did an OTA update for the MI1 firmware....

Enter:  "Firmware Update Error" (and a dead Andy lying on his back). Awesome. Could it be because I had rooted ME7? Probably. So, after doing a full factory reset - and then doing the update, it seemed to work.

But now, I have a completely blank factory-image phone... it might be the time to pull the trigger on a custom ROM.

To be continued.....

Tuesday, September 17, 2013

Setting Up RAID-1 on Linux Mint 15, Revisited using manual commands

So, after I ran the raider program a while back, I had to do some other things with my machine ~ and long story short, I had to run raider once again. Only this time, I didn't do it right (I used the machine for a full day after running the initial raider setup and before swapping the drives - meaning that when I finally got around to completing the "raider --run" step, things were out of sync and crapped out)...

Originally, I started with my /dev/sda having all my stuff on it and /dev/sdb being the blank drive I wanted to add as a new member of a RAID-1 array... but, instead, (thanks to my screw-up) I ended up with /dev/sdb getting my system (thanks to raider's first step) and /dev/sda getting completely erased. Not a complete disaster, since I still had all my stuff on at least one of the drives, but I didn't have the time to wait for two more rebuilds, nor the patience to swap drives and stuff. So, I decided to jump in and try to figure out mdadm, proper... at least this was a good introduction to a little bit of the utility.

Since my mdraid had already been created (again, thanks to raider), all I needed to do was manage the array. So, the first thing I wanted to do was copy sdb to sda. This turns out to be pretty easy:

  • First, copy the partition table from your source drive to the new RAID member drive:
    # sfdisk -d /dev/sdb | sfdisk /dev/sda
  • Then, add the erased disk to the raid array:
    • Add /boot partition
      # mdadm --manage /dev/md0 --add /dev/sda1
    • Add / partition
      # mdadm --manage /dev/md1 --add /dev/sda3
    • Add /home partition
      # mdadm --manage /dev/md2 --add /dev/sda4
At this point, I checked the array (# cat /proc/mdstat) and discovered, to my surprise, that the array was already rebuilding (i.e. copying stuff from my sdb to my sda)!

Mission accomplished: I can now continue using my machine while the array rebuilds in the background. Since that will take another day or so, I'll continue this if there are other issues.....

To be continued?!


Wednesday, September 11, 2013

Updating the "WP to Twitter" WordPress Plugin to Fix "Code 410" Errors

I found myself in the position of needing to update our "WordPress to Twitter" plugin (http://wordpress.org/plugins/wp-to-twitter/) from version 2.6.7 to 2.7.3, due to getting a constant "Code 410" error whenever we tried to do a post - apparently an issue with Twitter's 1.1 API update. Here's how I did it:

  1. Deactivated the old wp-to-twitter plugin, using the WordPress "Plugins" admin-console.
  2. Using a Linux terminal with direct server access, I scp'd the new version's ZIP file over and unzipped it into my /wp-content/plugins directory.
    • When prompted to overwrite files, I chose "A" for all.
  3. Went back to my plugins admin-console, refreshed the page and reactivated the plugin.
All settings (including my Twitter API keys/tokens/secrets, bit.ly, etc.) were miraculously still there, and the new version appears to be up and running. Quite a nice surprise, when it comes to managing WordPress!

Tuesday, September 10, 2013

Randomly Rotate Strings for Display on a WordPress Page Using PHP (Shortcode Exec)

I was asked by our marketing team if we could have our WordPress-based homepage randomly display one of several possible tag lines. Well, sure... with PHP it's dead simple. And if you have Shortcode Exec PHP installed in your WordPress site, it's actually even easy under WordPress.

Here's how I did our particular page. It will randomly choose a string from a PHP array, and present it in a clean looking, rounded-corner wrapper. If you use this, of course you may want to modify the strings and styles to suit your needs. Note, rounded corners aren't fully supported by most IE versions ~ I try not to waste time developing for IE, but if you have a solution, feel free to post it here.

Create a new Shortcode Exec PHP like so...
/* Rotate random hyperbole lines on the homepage */
$hyperboleStrings = array(
1  => "We have the best product",
2  => "Our solution solves problems",
3  => "Industry leading solutions"
);
$whichStringToShow = rand(1, sizeOf($hyperboleStrings));
echo $hyperboleStrings[$whichStringToShow];
Now all you have to do is save it and go to the page you want to add it to. In my case, I had to go to Appearance -> Editor -> header.php...
<div class="rounded_corners" id="hyperbole-line">
<?php echo do_shortcode("[homepage_hyperbole_rotator]"); ?>
</div>
And, here's my CSS...
.rounded_corners {
-moz-border-radius: 10px; /* firefox */
-webkit-border-radius: 10px; /* safari, chrome */
-khtml-border-radius: 10px; /* KDE HTML layout engines */
border-radius: 10px; /* css3 */
}
#hyperbole-line {
background-color: #20b0b0;
width: 85%;
padding: .25em;
text-align: center;
margin: 10px auto 10px auto;
color: #fff;
font-style: italic;
font-size: 1.75em;
padding: 0;
letter-spacing: 1px;
}

Monday, September 9, 2013

Can Philips Hue Lights be Controlled by Third-Party Controllers?

In developing applications with the Philips Hue lights, it's become painfully apparent that the "bridge" (the white circular control device that comes in Hue starter kits) is pretty inadequate. Philips has not been very developer-friendly to those of us with more advanced needs than a disco smartphone app.

The woefully inadequate bridge has rate limiting... it does stuff that you may not want it to, in ways that you may not desire... not to mention that you're pretty much stuck with their paltry API and its limited functionality, etc. Basically, it's like being stuck with an old un-rootable Android phone, when you could otherwise breathe new life into it (and have advanced capabilities) by flashing a custom ROM to it (Apple fans: substitute jail-breaking for this analogy).

So, I got to wondering: why couldn't the lights can be controlled without going through the Philips-supplied, Philips-controlled bridge? The bridge is just an IP-to-Zigbee gateway... in other words, it connects two separate networks: your IP network and the lights' wireless Zigbee network.

If there were some other third-party device that would do this -- one which would give you more direct control of the lights, then you could seemingly go completely around Philips' restrictive control, right? If my server could have more "direct" access to the Zigbee network, I think I could do some pretty slick things... right?

Enter, the Digi ConnectPort X2e.
I found this product via a co-worker's suggestion (he's had recent experience with Zigbee devices), and it's basically just a programmable IP-to-Zigbee gateway (probably just an embedded Linux SoC). Hmmmm.... now I just need to figure out how to develop it's Python-compatible programs on a Linux machine (they seem to only offer an IDE running under Windows or Mac).

So it begins, my venture deeper into advanced Philips Hue light development; and, moreover, further opening the door to the M2M world. More hopefully to come...

Friday, September 6, 2013

Setting Up RAID-1 on Linux Mint 15, Made Easy

Having come from the RHEL/CentOS world, it was a bit of a surprise to me when I installed Linux Mint 15, and noticed the lack of a software RAID setup step during the install process. But this can easily be done once installation is complete ("easy," relative to manually running mdadm, anyway).

Here's a handy little tool I found to ease the implementation of software RAID-1: raider (http://raider.sourceforge.net/).

By using this tool, I didn't lose any data or anything... just installed the OS and then ran raider after the fact. It really wasn't too painful (just takes some time and requires pulling cables a couple times). And, don't be put off by the low version number ~ it worked great for me, for this purpose.

My hardware consists of two hard drives, as follows:
(no LVM, no encryption - just plain, pure hardware devices)
/dev/sda  (2TB WD-black - Linux Mint 15 already installed)
/dev/sdb  (2TB WD-black - some previous file system I don't care about anymore)

If you follow the directions (including physically swapping the two hard drives' SATA cables and allowing them to rebuild), you'll get great results... at least I did.

  1. Download and then extract the package (I used version 0.13.2) anywhere (I used my ~/).
  2. CD into the raider directory and install:
    $ sudo ./install.sh
  3. Make sure you have the required packages installed (I only needed mdadm):
    $ sudo apt-get install mdadm parted sfdisk hdparm rsync bc wget
  4. Make sure you have at least one of the following installed (I already had mkinitramfs): dracut, mkinitcpio, mkinitramfs, mkinitrd, or genkernel
  5. Backup your stuff! (duh) ~ I didn't need to resort to it, but you never know.
  6. Reboot into single user mode:
    1. When booting, hold the shift key until you see the GRUB boot screen.
    2. Press "e" to edit the line, and append the word "single" (without quotes) at the end of the line (in my case, after the "ro quiet splash" part)
    3. Press "Ctrl" + "x" to execute the boot (it'll drop you into command line mode)
    4. Log in as root.
  7. Run the following command... raider will use the drive in the first physical slot (almost always sda) as the "source" drive and you will lose whatever is on the second drive (sdb). Be aware that this might take a long time ~ it took around 5 hours with my 2TB drive that had about 500GB of stuff on it.
    # raider -R1 sda sdb
    • Note: If your sdb had stuff on it before (especially RAID), you might get a message about needing to erase it. If you do, just run the command it says to run: raider --erase /dev/sdb
    • Note: If you get the "fatal error" about not being able to format a particular partition (in my case, it was the swap partition of the old disk), then you'll need to first do an fdisk on sdb, and delete all the partitions (just to be safe - you don't care about them anymore, anyway, right?). Be sure to reboot after you write the changes in fdisk. Then run the raider command again.
  8. Once that completes...
    1. Shutdown the machine
    2. Physically swap the two hard drives' data connectors with each other
    3. Boot back into single user mode (repeat step 6 above)
  9. Run the command:
    # raider --run
    • Essentially, we've now simulated a degraded array (sdb isn't complete, but we're booting from it as sda this time), and we're now going to rebuild it. Other than copying the sda's contents to sdb, the added bonus is that we're also testing the array's ability to rebuild here.
    • Note: this will take quite a long time... for my 2TB drives, it took about 8 hours!
  10. Once that completes... (at this point, you should now have two identical drives as members of a functional and working RAID-1 array)
    1. Shutdown the machine
    2. Physically swap back the two hard drives' data connectors with each other (the way they were originally)
    3. Boot back up as you normally do... you're all done!

Thursday, September 5, 2013

Exclude WordPress Recent Posts Having a Certain Category

Say you have a homepage that you list recent posts on, using the "Recent Posts" widget or something.

Also say that you want to exclude posts that have a certain category. In my case, I have regular blog posts, and I also have a category of blog posts for "Press Releases" that I have a separate section on my homepage for.

Well, I don't want duplicated post links on my homepage, now, do I?

So, here's the hack (I prefer to avoid the term "solution" when dealing with WordPress)...

In my theme's functions.php file (Appearance -> Editor -> Theme Functions), I added the following bit of code at the end (change the red text to the appropriate ID of the category you wish to exclude - you should be able to specify multiple categories by separating them with spaces e.g. '-1 -2 -3'):
function exclude_category($query)
  {
  if ( $query->is_home() )
    {
    $query->set('cat', '-TAG ID OF CATEGORY');
    }
  return $query;
  }
add_filter('pre_get_posts', 'exclude_category');
From what I'm able to gather, the function intercepts the standard procedure for getting posts, via the add_filter function. More of your typical WordPress voodoo black magic, if you ask me... building layers upon layers upon layers /smh.

Friday, August 30, 2013

Philips Hue: So Close, yet...

Having developed my company's signal light product (one of our first "internet of things" devices), I had the fortune to play with the Philips Hue lighting system... from as high level as the official mobile app, down to the API, and even as deep as the Zigbee protocol underlying it all.

I actually dived into the project thinking that it would be a lot fun (after all, what's not cool about stuff like sending curl commands to a friggin' light bulb?). But instead, my enthusiasm was eventually dampened by problems like the following:

  • An incomplete API
    • Just try to delete a light bulb without doing a factory reset
    • Pointsymbols, anyone?
  • Strange colors
    • Non-RGB LEDs with impure colors (but, admittedly, good whites)
    • Unable to light just one color of LED at a time
  • Haphazard firmware updates
    • Updates that break or reset important things (like which bulb is which)
    • Minimal changelog documentation, if any
    • Different updates for bridge vs. bulbs... can't update bulbs manually nor rely on automatic updates
  • An arbitrary bulb addressing scheme that can change on a whim (like w/updates) ~ Philips, please give us access to the bulbs' unique identifier! If nothing else, then this at least! That way, at least when you push a light bulb firmware update to us (without permission or acknowledgement, by the way), it won't matter that bulb #2 is now addressed as #5 or something.

I found it simply astounding that a massive global company can release and promote such a polished-looking product (they certainly focused intently on packaging), while the underlying code and logic is so incomplete and buggy. The API and associated logic all seemingly borrows from existing off-the-shelf technologies (JSON, UPnP, Linux -I'm nearly certain, etc.); but, frankly, looks like it hasn't had quite the development effort it probably should have been given... it just really seems like it would have been pretty easy to release a more robust API.

I can understand releasing a version 1.0 API for bleeding-edge technology; but these bulbs have been out for over a year now. With their popularity and enthusiast userbase, we should be up to 2.0 at least, by now. At least, if things were open sourced, we'd be making some better progress, I bet. But, Hell, it took twisting Philips' arm by the community to get the API "opened" (read: documented).

Meanwhile, a major crowd-sourced project has completely opened their API and source code, and has a light with superior qualities, all around. Why you no fear obvious competition, Philips?

Thursday, August 22, 2013

Firing CSS3 Transition on Page Load Event (in WordPress)

CSS3 has some pretty cool stuff ~ among these are transitions and animations. So, when I was tasked with making the tagline on my company's website "pop" or stand out somehow, CSS3 is the first thing that came to mind.

It was fairly easy, but the one trick I needed to figure out was how to make it all happen when the page is finished loading -- of course, WordPress didn't really make this easy on me... it has a nasty habit of not rendering or interpreting the code that I tell it to. Naturally.

Anyway, here is the tagline...
(forgive the poor quality of the GIF I used to record the browser window)




Here is the HTML event hook, which I added this to my header.php file...
(don't you just love that WordPress syntax BS?)
<script language="JavaScript" type="text/javascript">
// <![CDATA[
window.onload = function(){
  document.getElementById("body").setAttribute("class","loaded"); }
// ]]>
</script>

And add an ID attribute to the body tag, with a value of "body" for the hook above...
(ignore the elipses, I have other stuff in that tag that you don't need to care about)
<body id="body" ...>

Here is the CSS...
(the tagline container is classed "header-right" ~ the only thing you need to care about is the "#body.loaded" selector)
.header-right div {
  color: #ffffff;
  font-size: 1.8em;
  font-weight: normal;
  text-align: right;
  line-height: 1;
  margin-right: 15px;
  font-style: italic;
  text-shadow: 0 0 0 #dd5500;
  /*the following configures our transition effect - 500/200ms are
    delays to give the page time to render before doing transitions*/
  transition: color 2500ms ease-out 500ms, text-shadow 2000ms ease-in 200ms;
}
#body.loaded .header-right div {
  color: #178582;
  text-shadow: 0 0 180px #ff9944;
}

How does it work? Well, basically, you give the body node (which is what onLoad works with) an ID that we can later use to grab it and work with. Then, a JavaScript listens for the onLoad event; and when it fires, that same JavaScript will apply an attribute (class="loaded") to the body tag. Then, CSS will naturally go in and apply the transition effect (since the selector for "loaded" now exists in the document).