Sunday, October 6, 2013

CSS

So a lot of what I do at work ends up being targetted for the web. Despite me thinking web programming is a blight on humanity. Realistically, I've managed to abstract away the web-ness of most of it behind some decent libraries, so I can pretend it's not the web. But occasionally I have to actually write some HTML and CSS.  And let me tell you, my opinion is that CSS is AWFUL.

Here's why:

1. It's unintuitive and inconsistent.

I'm not talking about the general concept, or the block model. Sure, you have to learn those. But they aren't hard. I'm talking about stupid stuff like vertical-align, which means two completely different things depending on the context. In a table cell, it means one thing. In an inline element, it means something completely different. 

Or absolute positioning. One would think positioning of "absolute" instead of "relative" means positioning the element absolutely. Instead, it's just a different type of relative, technically: "In the absolute positioning model, a box is explicitly offset with respect to its containing block" ...or in other words, it's relative to some parent above it. (W3Schools states it as "An absolute position element is positioned relative to the first parent element that has a position other than static.")

It also kills me that specifying a width of 100% for an element gets really messy if there's a margin or padding. Because the padding is included in the 100%, but the margin isn't. Or maybe it's the other way around? I'm sure CSS junkies remember. Normal humans don't. All I know is that percentage widths break down when margins and padding are around. 

Now I know people that are used to CSS will defend many of these things, but having used a large number of other layout toolkits in other programming environments, none of them make me scream and pull my hair out like CSS does.

2. No grid layout.

Why, oh why, isn't there a grid layout? Maybe because the table html element already exists, which is a perfectly good grid layout. Oh wait, all presentation-related code is supposed to be moved to css, and tables should only be tables of data.  Unfortunately, there's no real replacement for tables for grid-based layouts. So for a layout that should naturally be a grid (ie a form of labels and text fields), you end up with a mess of absolutely sized nested divs or other ridiculous workarounds.

People have come up with all sorts of hacks and frameworks to get around this issue. Great, we can hack our way past it. It's still terrible design.

3. It replaces one set of hacks and problems for another set.

When people first got all excited about separating content from presentation, it seemed like a good idea. Unfortunately, HTML and CSS are terrible at letting you actually do so for any vaguely interesting design.  So either your presentation bleeds into the content (37 divs for a piece of content, just so the header, header corners, edges, etc, can all fit together to make it look right), or you end up with all sorts of hacks and nastiness in CSS and Javascript frameworks to try to trick your browser into doing something it wasn't designed to do.


So what can we do about it? Not much, unfortunately. The web is what it is. All sorts of CSS and javascript framework are written to try to make it easier. I guess you can use one of those. Or maybe just avoid web programming in general, that seems more pleasant.

Saturday, October 5, 2013

Debugging on Pebble

So I'm currently working on a fancy alarm clock app for Pebble for a friend of mine.  It allows up to 10 independent alarms, with different schedules (and different types of schedules, ie "every day at 9am" or "every 2 hours"), and the ability to sync (using HttPebble) with a web app so that the alarms can be managed from a web page, and to synchronize their status (since there's no persistence on the pebble itself).

Let me just say, this has been harder than I expected.

The first draft, to get the alarm functionality working, was actually pretty straightforward. I wrote the code, pushed it to the watch, and, with a couple obvious tweaks, it just worked. When does that ever happen?

The next step was to use the HttPebble protocol to sync stuff (yes,  my friend uses iOS) This has been the painful part.  Let me count the ways:

1. I have to do a fair bit of string manipulation in passing data back and forth. Anyone who's done much with C knows how primitive the string manipulation functions are. To top it all off, Pebble's limited environment doesn't even include all the standard C string functions, so I had to rewrite a simple implementation of a few of them.)

2. There's just no real testing/debugging tools for Pebble. During the kickstarter project they said there'd be an emulator, but it's pretty clear that they promised more than they could provide. When it doesn't work, it's really hard to tell why.

3. I've had some weird network issues at home that have made it even harder to test, because I'm never sure if it's my code or if my phone just can't talk to my test server.

Ugh.

I think I'm finally getting close. The watch properly (via the phone) sends the status of any repeating alarms to the server, which saves them and can echo them back to the pebble. The only thing I need to fix is the pebble parsing and understanding the alarm definitions that the server sends, which it's currently failing to do.

Monday, August 26, 2013

Pebble review revisited

Well, it's been a few months since my rather negative review of my Pebble. So now that they've released a couple versions of the SDK, it's time to restate my opinions.

First, please note that I'll be specifically referring to using the Pebble with an Android phone. Due to the developer restrictions in the iOS world, my coworkers and I haven't found iOS apps that interface with the watch to make it do cool things. There's a primitive http tunnel app (HttPebble) that lets watch apps communicate with specially coded websites. But that's all I've seen. (if anyone knows of any, please let me know!) Until things change, I wouldn't bother with a Pebble if you use iOS -- you can't do much more than you could when I wrote my last review. Sure, there are a few watchapps that don't require communication, but those are of limited functionality. And the HttPebble tunnel is limited enough to keep it from being a general solution for integrating with many external websites.

But in the Android world, people have jumped in and written apps to make the Pebble start to fulfill the promise of the "smart" watch. First, I'm still rather unimpressed with the software created by Pebble itself. It takes the development of these 3rd party apps to accomplish what I expected Pebble to actually come up with in the first place.

That being said, there are 2 Android apps that deliver a pretty good "smart watch" experience: Glance for Pebble and  Canvas. for Pebble

Glance for Pebble

Glance is the first of the two that I discovered and tried, and the first Pebble app that made my Pebble useful. It has a few options for the display, which includes things like weather, missed calls, missed email, etc. The other nice thing about it is that is has quite a bit of interactivity. You can send pre-written text messages, launch tasker scripts, etc. Overall, it's pretty nice, although the main watch face isn't extremely configurable. 

Canvas for Pebble

If being configurable is what you are looking for, Canvas for Pebble is amazing. It features an on-screen designer (on your phone) to customize your watchface. You can add layers, move them around, hook into phone sensors, tasker variables, weather, etc. And it features a plugin system so you can write your own layer types. I've been using a custom watchface that shows date, time, weather, missed phonecalls, number of unread emails, my next appointment on my calendar, and a small noitfication if my phone and watch disconnect from each other (ie if I left my phone somewhere).  I have vague plans to add a few custom plugin layers, if I ever get around to it, but we'll see.

While it doesn't have any interactive features (you can't control things from the watch, it's merely a watchface), it's amazing as far as getting your watch to look the way you want. 



So that all said, I finally feel like the Pebble is neat. My watch is "smart" now, whatever that means. 

There are some problems still. I get random disconnects every few days, that usually require me to turn off bluetooth and turn it back on before it will reconnect. The music control and display feature built into the watch doesn't work well with Pandora. Battery life is shorter with these smarter watchfaces (usually 5 or 6 days instead of the 7-10 I was getting). But overall, it's not a bad product at this point. Although I'm still not convinced it's worth the price.

Wednesday, March 13, 2013

Tasker

Ok, I have to rave about my favorite thing for Android -- Tasker. If you own an Android phone, and you enjoy the process of fiddling about to make it more and more useful, then Tasker is the best thing ever.  It's an app that lets you basically attach various actions (changing settings, playing notifications, launching apps, etc) to various triggers (locations, times of days, phone sensors, phone calls/texts -- just about anything you can think of) in all sorts of interesting and complicated ways.  It's relatively expensive for an Android app (around $6), but worth every penny.

The only problem is the user interface -- it has a goofy unintuitive UI that makes it pretty cumbersome setting up complex profiles. I'd pay another $6 for a decent editor on my actual computer. (It's tempting to write one, as tasker saves and loads its profile scripts as xml).

That all being said, here's the things that I currently use it for:


  • When headphones (without a microphone) are inserted, and there's no media already playing, immediately launch my last music player and resume the last song.
  • Mute the phone on sunday during church time, and restore the volume afterwards.
  • Mute the phone if it's being charged after 10pm. (I always charge it while sleeping, so I figure if I'm up after 10, I want it to ring until I put it on the charger. And if I'm charging during the day, I want to hear it).
  • It checks my work calendar, and automatically mutes if it's during the time that I have a meeting scheduled (and restores the volume afterward)
  • If Sara's calling, it vibrates with a crazy different pattern, to make it more obvious that it's her.
  • If I get a call that's a non-217 area code, and not in my contact list, it's a different ringtone (I've gotten a lot of phone spam recently, so this makes it obvious it might be spam)
  • If I get a call from a number I've previously marked as spam, it doesn't even ring.
  • If I text a secret code to my phone (or Sara's), it turns to full volume, and rings like crazy (to help find the phone if we've misplaced it, or if I know Sara muted her phone and I need to get her attention)
  • If I receive a text message, and I'm in the car (based on being connected to the bluetooth device in my car), it reads the text aloud over the audio.
  • If I get a text message, and I'm not at my desk at work, it forwards the text on to my pebble watch. (If I'm at my desk, I get the text notification on my computer, so I don't want it to bother with my watch).  To check whether I'm at my desk, it does a web query to a URL I set up on my work machine that simply reports the time since the last input. If that number is bigger than a few minutes, it assumes I'm not at my desk.
  • I haven't finished setting this up, but I want to do the same thing with gmail -- if I'm not at my desk, forward the message summary (First few lines) on to my pebble watch.

That's just a tiny sample of what this thing can do.  There's a thread here on Reddit with people listing cool things they've made it do, and some other interesting samples on Tasker's site. Like I said, if you have an Android phone and you enjoy futzing around to automate your life, Tasker is absolutely worth it.




Tuesday, March 5, 2013

My Pebble Review

Since everyone and their uncle is talking about their brand new Pebble, I guess I can chime in with my review of the current state of the Pebble. I've had the Pebble for a few days now, so I've had some time to play with it and see what it has to offer.

First, the physical appearance and feel (the unimportant stuff). It's a little bigger than I'd really like, but still fits comfortably on my wrist. The included watch band feels a bit rubbery and cheap, although it's a standard band and easily replaceable, so I'm not too concerned about that (as a side: the Pebble makers seem awfully proud on their twitter stream about the fact that the band is customizable. Maybe that's because nothing else on the watch is customizable yet?) It's held a charge well so far (I charged it 4 days ago), so it will easily last a long weekend, which is my cutoff for real use (I don't want to haul along a watch charger for a weekend trip!) So overall, the physical package is decent, although nothing amazing or mind blowing.

That leads to the next part: the built-in software. The pebble was supposed to come with a set of built-in functionality, as well as feature an SDK and the ability to load custom apps. All of the promotional information about the pebble talked about integration with things like RunKeeper, ifttt, golf range finder apps, etc. Unfortunately, none of those apps actually exist. Pebble claimed that the SDK would be released before the watch was shipped, but there's been no sign of an SDK yet, no apps, and worse: no announcements about any sort of timeline for it. Without a timeline or any announcements, one has to assume that we might not see any custom software for a long, long time. So we're stuck reviewing what the pebble can do out of the box. And unfortunately, the answer is: not much.

The Pebble currently has a small handful of watchfaces. One of them, a text-based face, is well designed and nice looking. Most of the others aren't as nice looking, or are relatively gimmicky (such as a binary watch). So while it's fun to be able to switch watch faces, many users will only have one or two that they are actually happy with using day to day. 

The other two things the pebble can do are control music on your phone, and receive notifications. The notification system is the best part (or only redeeming part) of the Pebble so far. When I get a text message, it appears on my watch. The watch vibrates and shows caller id when I receive a call (And I can reject the call from the watch). It's also supposed to support email notifications, but for some reason, those don't actually work right now from gmail on many Android phones (including mine). So until those work, I don't really count that as a feature. It also claims to forward facebook notifications to the watch, but I don't have Facebook installed on my phone, so I can't test it. It DOES support google voice notifications, which I'm really happy about (as I do all my texting through google voice).

The music control is neat, and actually works. If you select the music app (a surprisingly cumbersome task requiring you to back out of your current watchface, dig through a list of all the watchfaces you've installed, and select the music player), it shows what song is currently playing on your phone, and provides the standard Bluetooth controls for play/pause, forward, and back. It's relatively cool, and works well, although to get back to your watch, you have to once again navigate through the menu to find your preferred watchface. If there's a shortcut to go back to watch mode, I haven't found it. The clunky interface deters me from using it as often as I might otherwise.

And so far, that's all it can do. To help a little, some smart person has written a 3rd party app for Android that lets you forward any notification from your phone to the watch, not just the few that Pebble officially supports. (I wonder why Pebble didn't just build that functionality in?) Still, there's no ability to actually control anything from the Pebble other than your music. And doing that requires navigating a relatively clunky interface.

I'm still excited about the future prospect of the Pebble. If the SDK gets released soon, it could end up being an exciting product. Or at least actually fulfill the "smart" part of the "Smart Watch" idea. Unfortunately, the longer they wait to release, or even officially announce a timeline for the SDK, the worse and worse the Pebble looks as a product. I love the theoretical future idea of the Pebble, but I'm not very impressed with the hunk of plastic currently on my wrist.

Pebble has said they first focused on getting the hardware right, and now they can focus on software. So if I think in terms of it being an unfinished product that they plan to finish later, it makes more sense. Because the watch currently on my wrist isn't by any means a finished product. I just wish they were more communicative about the timeline for finishing it.

I guess this quote from an article on TechCrunch about smart watches sums up my opinion about it:


A solid platform needs compelling applications. The promise of the smart watch is fine but, in actuality, it will take a while for this promise to come to fruition. By that time, I suspect, the mass of Pebbles will be lying at the bottom of a dresser drawer.
My friend who has a pebble has already stashed his in a desk drawer and gone back to a normal watch. I'm still wearing mine, hoping the novelty lasts long enough until the SDK is actually released, the promised apps arrive, and a finished product materializes.

Wednesday, October 3, 2012

Why I don't enjoy mobile gaming

Mobile gaming is all the rage. It's where the money is. It's where all the hip new games are. And by golly, it sucks.

I should like it. I love having a portable computer in my pocket to play games on. I like firing up a game while I'm sitting around waiting on something. I just don't like the games. Instead I buy all of Robert Broglia's excellent emulators, and only play ancient console games on my phone. I know this has been discussed to death, but hey, it's the internet -- what's the point of the internet if not to soliloquize into the ether?

So here I go, the main reason I don't like mobile gaming?

(And it's not the lack of control pad. I do miss a control bad, as touch controls are awful for certain genres. But this can be worked around with creative games, or with well-design onscreen touch controls (Robert Broglia did a pretty good job!)

Really, the big problem is long load times, and tons of slow menus.. This is the real kicker. When I want to sit down and play a game on my phone, it's because I have a couple minutes of downtime where I want to be entertained. I want to get into my game, play, and get out. The problem is most mobile games have enough splash screens, resource loading, menus, etc, that it takes forever to actually start playing.

I downloaded a cool game, Gravity Guy, from Google's 25cent app sale last week. Great concept for a game -- a simple gravity-reversal twitch game, reminded me of VVVVVV or my favorite mobile game, The Impossible Game. The only control is touching the screen at the right time. It's fun, fast, and great in short bursts. The only problem, (ok, not the only problem, the biggest problem) is that it takes forever to start playing. I timed it yesterday -- from the time I tapped on the icon until I was playing, took 35 seconds. (A splash screen, a title screen, 3 or 4 pages of animated menus, and another loading screen). That may be fine for a console game where you are planning to devote some time to playing a game, but for simple mobile games, hopping in and out, it's a waste.

Another game that I want to like is Highborn, a clever and relatively well-designed turn-based strategy game. I always enjoy it when I actually play it. But the barrier to start playing is just high enough that I never want to sit down and play it. It just takes too long to get started.

It's even worse when restoring a saved game takes me to some predetermined save point instead of exactly where I left off. Playing mobile games, I often end my game extremely suddenly. I want to resume just as suddenly, without replaying stuff.

There are a few other things that I don't like -- the ubiquity of microtransactions, ridiculous use of "unlockable" things, the tendency to repeat the same boring genres (tower defense, run & jump, etc), but these are all minor things.

Now there are TONS of games in all the mobile app stores. I'm sure there are other games that load quickly and aren't annoying. But how do you filter out and find them? There's no search options for "loads quick and doesn't tick you off with stupid stuff".

So instead I play old emulated cartridge-based console games. They load instantly (it takes about 3 seconds at most before I'm resumed to exactly where I left off). They save instantly.  Some still have annoying unlockable stuff, and there's a different uninspired set of genres, but I don't get pestered to buy something when I'm playing.

So what's my point? I guess if you are a mobile game developer, make your game load fast. That's all.

Tuesday, September 18, 2012

Coding for a broken phone

So I've been very slowly working on a project to create a network-based garage door sensor (and possibly opener) which will let me check whether the garage door is open (when I left for a trip and suddenly panic because I can't remember if I closed it), and will also alert me if it's after 10 and I accidentally left it open. (Eventually I'd like to add a controller, so I can open/close it from my phone, but that's a long way off).

The first step was finding an easy way to sense if the door was open, and report that to my home server so it could serve it up to me.  Luckily my office-mate handed me his old android phone with a busted screen. Nothing shows up on the screen, and it the touch sensors don't work. 

Theoretically, I can mount the phone near the top of the garage, and write a program for this phone that will monitor the proximity sensor to tell if the door is open or closed (if I position the phone so that the open garage door will sit right in front of the phone near the ceiling) then report that to the home server over wifi.

So the things I would need to figure out:

  1. Can I even get code running on this thing without ever touching the screen?
  2. Can I get the proximity sensor working?
  3. Can I get the phone onto my wifi without being able to use the wifi configuration UI?
  4. Can I figure out how to physically mount this thing on the ceiling of the garage so it will work?
  5. Can I do all that before getting bored with the project?

1 was easy -- plug in the phone, fire up adb, and go to town. The Android debugging tools work just fine. Luckily Tim had enabled USB debugging before breaking it, or I might have been completely out of luck.

#2 was easy as well. The API for handling the phone sensors is pretty straightforward and easy to work with.

#3 was the most painful. I spent a good while tonight trying to figure out if I could configure the wifi just using adb (the remote debug tool for android). Couldn't figure out how to do it. So then I found the API for doing it programmatically -- so I need to write a program to configure the wifi before doing the rest of the monitoring. The sample code was really simple. Unfortunately it kept not working. And not working. And not working. With no reason reported of why -- either the call to enable my wifi network just failed, or it succeeded, but never connected. *sigh*. Finally figured it out after a ton of mistakes (the most notable, if anyone is here looking for help, being that the SSID and password have to be quoted inside the string, like:  String SSID = "\"myssid\"";, and the Android manifest needs to specify some uses-permissions: CHANGE_WIFI_STATE, ACCESS_WIFI_STATE, and ACCESS_NETWORK_STATE) 

So I finally tonight got that working. Next step: write the code to tie all this together. Then try to figure out how to mount it on the ceiling. Someday I might actually finish this thing.

If anyone tries to do this as well, here's a snippet of code that worked for me:

In the manifest:
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
And the code itself:
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"mySsid\"";
conf.preSharedKey = "\"1234567890\""; 
conf.status = WifiConfiguration.Status.ENABLED; 
 
int res = wifi.addNetwork(conf);
wifi.disconnect();
wifi.enableNetwork(res, true);
wifi.reconnect();                
   
wifi.setWifiEnabled(true);

NES Anguna

Well, I had a little bit of time still, while Frankengraphics is finishing up her game Project Blue, to have a little downtime on Halcyon, s...