Tuesday, December 27, 2016

P12/PKCS12, JKS keystores, and passwords

We ended the day with a situation that confused us, in which Spring allowed us to specify passwords for both a KEYSTORE and the KEY within the keystore, but it only worked when the two passwords were the same. Below is me playing around trying to understand this, ultimately the explanation is this - PKCS12 does NOT support different passwords for the keystore and key. But other keystore formats such as JKS *do* support different passwords for the keystore and key. Spring supports both types of keystores, so it’s generic config file allows the specification of a key password for pkcs12 even when that password can’t – by definition – be used.


# generate a password-protected keypair. The password is used for pbkdf2 encryption of the keypair
openssl genrsa -aes256 -out keypair.pem -passout pass:abc123 2048

# create a self-signed certificate with the keypair from above
openssl req -new -x509 -sha256 -days 1826 -passin pass:abc123 -key keypair.pem -out selfsigned.crt -subj '/C=US/ST=MN/L=Metro/O=Hello/OU=There/CN=localhost'

# create a p12 formatted file containing the private key and the self-signed certificate
openssl pkcs12 -export -out keystore.p12 -inkey keypair.pem -passin pass:abc123 -in selfsigned.crt -password pass:xyz789

# given the above, and using the keystore.p12 file, the following TWO springboot ssl configs both are successful

server.ssl.key-store: keystore.p12
server.ssl.key-store-password: xyz789
server.ssl.keyStoreType: PKCS12

server.ssl.key-store: keystore.p12
server.ssl.key-store-password: xyz789
server.ssl.key-password: xyz789
server.ssl.keyStoreType: PKCS12

# interesting - we can specify the private key password as being identical to the keystore password OR we can not specify the private key password at all.

# let's use some incorrect passwords to learn a bit more. maybe the error message we get will be helpful.

# try this config that specifies an incorrect keystore password
server.ssl.key-store: keystore.p12
server.ssl.key-store-password: wrong
server.ssl.key-password: xyz789
server.ssl.keyStoreType: PKCS12

# when we start the application, it fails with this at the top of the stacktrace:
# java.lang.IllegalArgumentException: java.io.IOException: keystore password was incorrect

# makes sense. ok, what about this config, that specifies an incorrect private key password
server.ssl.key-store: keystore.p12
server.ssl.key-store-password: xyz789
server.ssl.key-password: wrong
server.ssl.keyStoreType: PKCS12

# when we start the application, it fails with this at the top of the stacktrace:
# java.lang.IllegalArgumentException: java.security.UnrecoverableKeyException: Get Key failed

# interesting. what can we infer from this?
# - Both the keystore and private key ARE password protected
# - Both of these passwords are the same. This point is interesting, given how we generated the private key and keystore. The OPENSSL pkcs12 command does NOT have an option to specify different passwords for the keystore and the private key contained within. The keystore that is output from the pkcs12 command MUST be using the same password to encrypt the private key AND the keystore itself. Yet SPRINGBOOT is clearly comfortable with using keystores that have different passwords for the keystore and contained private key...what gives?

# ok, so...let's play with the keystore using java's keytool instead of openssl and see what there is to see.
keytool -importkeystore -help

Imports one or all entries from another keystore

Options:

-srckeystore <srckeystore>            source keystore name
-destkeystore <destkeystore>          destination keystore name
-srcstoretype <srcstoretype>          source keystore type
-deststoretype <deststoretype>        destination keystore type
-srcstorepass <arg>                   source keystore password
-deststorepass <arg>                  destination keystore password
-srcprotected                         source keystore password protected
-srcprovidername <srcprovidername>    source keystore provider name
-destprovidername <destprovidername>  destination keystore provider name
-srcalias <srcalias>                  source alias
-destalias <destalias>                destination alias
-srckeypass <arg>                     source key password
-destkeypass <arg>                    destination key password
-noprompt                             do not prompt
-providerclass <providerclass>        provider class name
-providerarg <arg>                    provider argument
-providerpath <pathlist>              provider classpath
-v                                    verbose output

Use "keytool -help" for all available commands

# Check that out - keytool, unlike openssl, has distinct arguments for the keystore password and key password. Let's try it, importing the existing keystore and exporting it again with the same passwords for the keystore and the key

keytool -importkeystore -srckeystore keystore.p12 -srcalias 1 -destkeystore new-keystore.p12 -deststoretype PKCS12 -srcstorepass xyz789 -srckeypass xyz789 -deststorepass def456 -destkeypass def456

# ok, use that new keystore in our app and see what happens
server.port: 8443
server.ssl.key-store: keystore.p12
server.ssl.key-store-password: def456
server.ssl.keyStoreType: PKCS12

# yup that works. Let's try making the new keystore with different passwords for the keystore and contained key
keytool -importkeystore -srckeystore keystore.p12 -srcalias 1 -destkeystore new-keystore.p12 -deststoretype PKCS12 -srcstorepass xyz789 -srckeypass xyz789 -deststorepass def456 -destkeypass def654

# we get the following output
Warning:  Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified -destkeypass value.

# now that is SUPER INTERESTING. the keystore format we're using does NOT support different passwords!

# how about a different format for the keystore – will that allow different passwords? Let's try JKS
keytool -importkeystore -srckeystore keystore.p12 -srcalias 1 -destkeystore new-keystore.jks -deststoretype JKS -srcstorepass xyz789 -srckeypass xyz789 -deststorepass def456 -destkeypass def654

# ok, use that new keystore in our app. note the keystore type is JKS, and we're specifying the two different passwords we used in the above keytool command
server.ssl.key-store: keystore.jks
server.ssl.key-store-password: def456
server.ssl.key-password: def654
server.ssl.keyStoreType: JKS

# yup, that works. different passwords for the keystore and key. Let's make sure that's true. Run the app using the same password for the key as the keystore
server.ssl.key-store: keystore.jks
server.ssl.key-store-password: def456
server.ssl.key-password: def456
server.ssl.keyStoreType: JKS

# when we start the application, it fails with this at the top of the stacktrace
# java.lang.IllegalArgumentException: java.security.UnrecoverableKeyException: Cannot recover key

# so, what have we learned:
- Spring can utilize keystore files in different formats. We've looked at two of them here - PKCS12 and JKS
- Spring allows you to specify unique passwords for the keystore and key within the keystore. If the key password is not provided, Spring uses the keystore password as the key password
- The PKCS12 format does NOT support distinct passwords for the keystore itself and key within the keystore. These two passwords must be identical.
- THe JKS format DOES support different passwords for the keystore itself and the key within the keystore.

# I haven't yet dug into the history of these keystore formats to determine why the above behavior is true, but here's the tl;dr
- if you are using a PKCS12 formatted keystore, your Spring config should look like this
server.ssl.key-store: keystore.p12
server.ssl.key-store-password: <keystore password here>
server.ssl.keyStoreType: PKCS12
- if you are using a JKS formatted keystore, you Spring config can look like this if the keystore and key passwords are the same...
server.ssl.key-store: keystore.jks
server.ssl.key-store-password: <keystore password here>
server.ssl.keyStoreType: JKS
- ... or like this if the keystore and key passwords are different
server.ssl.key-store: keystore.jks
server.ssl.key-store-password: <keystore password here>
server.ssl.key-password: <key password here>
server.ssl.keyStoreType: JKS
- it is never correct to have this because the PKCS12 format does not support it
server.ssl.key-store: keystore.p12
server.ssl.key-store-password: <keystore password here>
server.ssl.key-password: <key password here>
server.ssl.keyStoreType: PKCS12



Thursday, May 12, 2016

WeatherClock - Part 5

Let's talk about the client side. As mentioned in earlier posts, I'm using an Arduino Uno with a CC3000 WiFi shield. The clock lighting is a ring of 60 NeoPixel LEDs.




The full source of the Arduino sketch is available here https://github.com/jimnelson2/WeatherClock-Client. I'll walk through it and then finish up by noting what work remains to be done, improvements could be made, and I how'd do this project differently now that I've done it once.

The sketch starts by defining a numerous constants - hardware references, constants, and globals used primarily for timing.

In the setup() function, we clear the NeoPixels to make sure they are off, initialize the CC3300 shield, and get the IP address of the server hosting our API described in the prior post.

In the loop() function, we first handle the "heartbeat" indicator. Since most of the time there is no weather info to display, I want an indication that the unit is functioning. I do this by lighting a single pixel every time we loop, which is every second. The LED to light is determined by simply mod-ing the sketch time by 60. This gives us, the appearance of a somewhat randomly selected pixel. It's nice.

After the heartbeat is handled, we check if it's been 2 minutes since our last call to the API. If so...we make the call. The API request is to the static API URL, and we include in our request header the calculated one-time password value needed for authentication. We make the call and assume success (more on that later). Our 60 characters of response to display on the ring are demarcated by the " character, so once we encounter or first " we use the next 60 characters to map into the array of 16 colors defined at the top of the sketch, setting each NeoPixel in turn to the mapped color. When all 60 LEDs have been set, we tell the NeoPixel ring to update and end the loop.

The remainder of the sketch code is composed of supporting functions such as OTP calculation, wifi shield functions, etc.

I mounted the NeoPixel ring and the Arduino inside a wall clock from Target that was only four bucks [http://www.target.com/p/room-essentials-9-wall-clock/-/A-50330028#prodSlot=medium_1_1&term=wall+clock]. The clock diameter was perfect for the ring, leaving about an extra inch all around and the depth of the clock left just enough room to mount the Arduino. I did all the mounting simply by drilling holes through the clock faceplate and securing the ring and board with twisted wires. I used a flexible cutting board (also from Target) as my diffuser. It was easy to cut with kitchen shears to the same dimension as the clock's cover and fits snuggly underneath.

Getting the diffuser to fit in the clock frame

LED ring mounted in frame

All electronics mounted. I am clearly NOT good at routing wires, but this works.


Among the work that remains to be done before I can really call this finished is:
  • My API call assumes success. When the call doesn't succeed for whatever reason, there is either no indication of the failure OR the NeoPixel ring ends up displaying some odd lighting combinations as a result of parsing HTTP error text rather than the expected colors indicators. The code needs to check for HTTP 200 and take action when a non-200 is received. I'm not sure what that action might be. Perhaps I could change the color of the heartbeat LED, or light a particular pixel based on the failure. e.g. If pixel 1 is a solid white, that could mean the API was unreachable, etc.
  • DNS lookup of the API occurs only during setup, and never again. I should be doing that lookup at some interval in case the mapping changes
  • Sometimes, the client will take upwards of 10 minutes before making a successful API call after powering up. I don't know why.
Improvements:
  • The heartbeat is a decent indicator of a functional client, but I'd like something "nicer". Maybe it could display an actual clock?
  • It might be nice to have the clock display an indication of weather alerts, e.g. thunderstorm warnings, etc.
  • The clock is quite bright in a darkened room, even with the LEDs set to very low power. I think two things can be done here. One, the diffusion panel can simply be thicker to block more light. Two, a photoresistor could be added to the circuit to automatically brighten/dim the LEDs based upon ambient light.
  • All of the useful settings - Location, one-time-password key, access point name/password -- are hard-coded. A "real" product would require a way to enter this information without having to compile and upload a sketch
What I'd do differently:
  • The CC3000 shield certainly works, but I found it challenging to use with respect to stability - my hardware would at times simply "lock up". By making my sketch size in RAM as small as possible, and doing all I could think of / find online to ensure the shield was working/connected the stability problem appears to be gone. But, this took a lot of time to figure out - probably more than any other part of the code. While I learned a lot in the process of making it work, I'd choose different hardware.
  • I might try a raspberry pi or other board. I never really exhausted the 2k of RAM or 32k of code space...but I got close. Given the improvements I'd like to make I'm not sure I can fit it all onto an Uno. Apparently it is possible to drive the NeoPixels from a pi...[link here]
  • Get more equipment. Some of those "third-hand" setups to hold wires while soldering would've been nice, as well as a big magnifying glass to see better, and a better soldering setup.
  • Beyond that...not much.
I'm pretty happy with how this has turned out. I don't know how long I'll keep this hanging on my wall but I'm enjoying it now. A couple more in-use pictures are below. All the pictures I've taken show it in a dark room, but that's just because it's the only way I could get a decent picture - my camera phone just washes out the images otherwise. The display is plenty bright even in a well-lit room.


Light rain starting in 15 minutes, continuing for at least 45

Medium/heavy rain for next 15 minutes, followed by light rain









Sunday, April 10, 2016

WeatherClock - Part 4

I need to describe the server-side part of this project in more detail since I've added to my scope. Here is a simple diagram of our entire system. In this post, I'm focused on the non-Arduino portion.

While I have no expectation that anyone else will use the service I've built, every call to the service results in a corresponding call to the Forecast.io API -- and my free account with them only allows 2000 calls a day. If more than 2000 calls happen, I stop getting a response from Forecast.IO, so my clock will have no data. The risk is small, both in it's likelihood of occurrence (nobody will really care about this service if they do find it) and in it's impact - my clock will stop working. While this isn't a big deal, I'd rather it not happen. So, how do I ensure that my public-facing Azure service doesn't get used/abused by anyone other than me?

Web services often use API keys to handle authentication -- you send a request with a valid key, you are authenticated. Forecast.IO does this, in fact. The downside of course is that if your API key is exposed, anyone can pretend to be you. I'm not concerned about this authentication mechanism b/w Azure and Forecast.IO -- that channel is relatively safe. I AM concerned about the channel between my Arduino client and my Azure service.

I could certainly use a static API key to authenticate my Arduino to my Azure service, but that's a bit riskier than a typical setup because I don't have the ability to create an encrypted channel. While Azure makes it free and easy to use SSL/TLS, my Arduino client is incapable of consuming it. So, our traffic will be in the clear over HTTP. How can I authenticate in the clear such that an eavesdropper can't make use of sniffed traffic? Here's what I came up with. Note this does NOTHING to stop a man-in-the-middle, it's just giving the observer of the traffic a harder job to make use of what is seen.

My Azure service exposes a single API: /api/Forecast/{latitude}/{longitude}/ . The header of the request must include two values: id and key. The value of id is essentially an "account identifier". Were I building a service that had multiple accounts/users, this would be the value to identify the account to which we want to associate the call. For me, this is a static, hard-coded value since I am the only account in use. The value of the key is the fun trick I'm using to get a semblance of authentication. The value of key is a calculated one-time-password, such as that used by Google Authenticator or any other 2-factor/OTP system. In fact, the OTP algorithm I'm using is fully compatible with Google Auth. So, here's how it works. My Azure service has a secret key associated with my account (again, this is hard-coded in my setup since I'm the only user), and the exact same key is also embedded in my Arduino. Assuming my service and my Arduino have their clocks in sync (to a reasonable degree), the two sides can calculate an identical 6-digit OTP that changes every 30 seconds. What does this do for us? It means that every 30 seconds, the header value that has to pass to my service to get a successful response will change. Neat - I have a non-static, unpredictable (from the outside) authentication mechanism! Obviously this is not bulletproof. I've done nothing to stop an eavesdropper from re-using a valid OTP within the same 30 second window for which it was calculated (tho' that wouldn't be too hard to stop). I'm sure there are plenty of other vulnerabilities as well. But I think this is a secure-enough solution for what I'm trying to accomplish. And given that I only have 2k of RAM to work with on the Arduino and a ton of other stuff to do in that memory space, I'm pleased with it.

The code for my server component is here: https://github.com/jimnelson2/WeatherClock-Server I put the source there for folks to see/use, but I used visualstudio.com and continue to use that for my development work.

Here's a quick walkthrough of the code. This is a standard .net WebAPI project, I've created only two unique classes - the ForecastController to handle the call/response with the Forecast.IO service, and the ApiKeyHandler to do the OTP/authentication work. The Forecast controller is wired in with the WebApiConfig, which also sets up the ApiKeyHandler. Small bits and pieces are scattered in to try reducing the size of the response back to the Arduino. By default, responses include lots of header data that just doesn't matter for my purposes. I could probably reduce a bit more, but this is good enough.

I use AppSettings to hold several handy values. First and foremost, the Forecast,io API key I use to authenticate my Azure service to the Forecast.io service. In development, this value is in the web.config. In production, this value is set via my Azure configuration so there's never a need to put my key into source control. In addition to the API key, I also use a setting for the OTP key (again, I'm the only user of this sytem - if it were multiuser, the OTP would be in a database along with my account id, etc.)  I use a few other values to help with development/debugging. For example, if I've set app settings for latitude and/or longitude, those values will override anything that comes in a request.

I've also made extensive use of application tracing commands. These are handy for when you need to crank up the logging level of your app. A simple toggle in your Azure panel will start tracing and you can pull the traces back either via the VisualStudio IDE, the web, or Powershell. Search the help docs on Azure for details.

As I've mentioned before, very little of this code is mine. I've documented in the code where I've sourced, primarily the Forecast.IO client and the OTP code.

About the response I send from the service back down to the client. I had initially designed things such that the response would be 60 RGB tuples - this would let me control server-side the exact color of any LED in the ring. e.g. 0,0,255,0,0,255...would set the first two LEDs of the ring to bright blue. After LOTS of frustrating testing I discovered what I should've known instantly - that's a lot of data for the Arduino to handle. So, I redesigned a bit. Instead of 60 RGB tuples (potentially 60 * 3 bytes, comma-separated), I send just 60 single characters. Each character is a hex value from 0 to f. That gives me 16 potential colors to specify, 0 is for an off/dark LED, while the remaining 15 are used to map into an array of 15 RGB tuples set as constants on the Arduino. This shrinks the network payload dramatically at the small expense of flexibility. Should I want to change my colors, I have to jump into the Arduino code. The smaller payload has dramatically improved Arduino stability, but I'll talk about that more in the next post when I go over the client.

Here's a look at the final product as a teaser - it shows a band of medium/heavy rain passing through in the next 15 minutes, followed by light rain wrapping up within the next 45 minutes.



Thursday, March 3, 2016

Calculate the entropy of a string (i.e. a password) with PowerShell

As with my other PowerShell stuff, this was made for fun and might make it's way into something later. The details of what the script is for, and the many assumptions it makes are in the code. Short story, this function will give you the bits of entropy in a provided string. Usually such a thing is interesting when trying to determine the "strength" of a password. The larger the number, the stronger the password (because the amount of space that would need to be explored to find the password via brute force is larger...has more entropy). The code notes a link that discusses the topic in MUCH greater detail.


 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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<#
.SYNOPSIS
    Calculate the entropy (in bits) of the provided string
.DESCRIPTION
    Based primarily upon discussion here, https://technet.microsoft.com/en-us/library/cc512609.aspx
    this function will calculate the entropy of the provided string, returning an integer result
    indicating bits of entropy. Numerous assumptions MUST be made in the calculation of this
    number. This function takes the easiest approach, which you can also read as "lazy" at best
    or misleading at worst.

    We need to figure out the "size" of the space from which the symbols in the string are drawn - after
    all the value we're calculating is not absolute in any way, it's relative to some max/min values. We
    make the following assumptions in this function:
    --if there is a lower case letter in the provided string, assume it's possible any lower case letter could
      have been used. Assume the same for upper, numeric, and special chars.
    --by "special characters" we mean the following: ~`!@#$%^&*()_-+={}[]|\:;"'<,>.?/
    --by "letters", we mean just the letters on a U.S. keyboard.
    --no rules regarding which symbols can appear where, e.g. can't start with a number.
    --no rules disallowing runs, e.g. sequential numbers, sequential characters, etc.
    --no rules considering non-normal distribution of symbols, e.g. "e" just as likley to appear as "#"
    The net impact of these assumptions is we are over-calculating the entropy so the best use of this
    function is probably for comparison between strings, not as some arbiter of absolute entropy.
.PARAMETER s
 The string for which to calculate entropy.
.EXAMPLE
 get-StringEntropy -s "JBSWY3DPEHPK3PXP"
.NOTES  
 FileName: get-StringEntropy
 Author: nelsondev1
#>

function get-StringEntropy {
[CmdletBinding()]
Param(
    [String]$s
)

$specialChars = @"
~`!@#$%^&*()_-+={}[]|\:;"'<,>.?/
"@

    $symbolCount = 0 # running count of our symbol space

    if ($s -cmatch "[a-z]+") {
        $symbolCount += 26
        Write-Verbose "$s contains at least one lower case character. Symbol space now $symbolCount"
    }
    if ($s -cmatch "[A-Z]+") {
        $symbolCount += 26
        Write-Verbose "$s contains at least one upper case character. Symbol space now $symbolCount"
    }
    if ($s -cmatch "[0-9]+") {
        $symbolCount += 10
        Write-Verbose "$s contains at least one numeric character. Symbol space now $symbolCount"
    }

    # In the particular use, I found trying to regex/match...challenging. Instead, just going
    # to iterate and look for containment.
    $hasSpecialChars = $false
    foreach ($c in $specialChars.ToCharArray())
    {
        if ($s.Contains($c))
        {
            $hasSpecialChars = $true
        }
    } 
    if ($hasSpecialChars) {
        $symbolCount += $specialChars.Length
        Write-Verbose "$s contains at least one special character. Symbol space now $symbolCount"
    }

    # in a batch mode, we might want to pre-calculate the possible values since log is slow-ish.
    # there wouldn't be many unique options (eg 26, 26+26, 26+10, 26+16, 26+26+10, etc.)
    # ...though in comparison to performing the above regex matches it may not be a big deal.
    # anyway...

    # Entropy-per-symbol is the base 2 log of the symbol space size
    $entroyPerSymbol = [Math]::Log($symbolCount) / [Math]::Log(2)
    Write-Verbose "Bits of entropy per symbol calculated to be $entroyPerSymbol"

    $passwordEntropy = $entroyPerSymbol * $s.Length

    Write-Verbose "Returning value of $passwordEntropy"
    return $passwordEntropy # this is the bits of entropy in the starting string
}

Saturday, February 20, 2016

WeatherClock - Part 3

Let's look at the server-side portions first. We'll do this in two parts and this initial one is trivial. We're going to be using the Forecast.IO API at https://developer.forecast.io/ to source our weather data. I'm going to be writing my server portion of this app in .net b/c I like it and I love Azure. It's just super quick and simple. Rather than writing my own wrapper to consume the Forecast.IO service, I'm going to use some lovely code found here: https://github.com/f0xy/forecast.io-csharp . This wrapper is PERFECT for what I need, and only needed two small enhancements.

First, the wrapper as-is does not include Precipitation Type for the minute-by-minute forecast. Easy enough to add, we just PrecipType to MinuteForecast in https://github.com/f0xy/forecast.io-csharp/blob/master/forecast.io/Entities/ForecastIOResponse.cs

Second, the wrapper needs an API key when it calls Forecast.IO. Rather than embedding the key in code, I made the trivial change to have the code pull the API key from my Azure app settings. This is a better solution as it keeps secrets completely removed from the code base.

Ok, that's a description of half our server side. Next post will wrap up the server-side code and provide reference to the full source.

Monday, January 4, 2016

WeatherClock - Part 2


First, the hardware. I got EVERYTHING from Adafruit.com. We have three primary components: An Arduino, a Wifi shield, and 4 1/4-ring Neopixels. I also got all my bits of wire and solder and sundry components from Adafruit as well.

Let's look at the hardware first. Here's what we're building. Note in this diagram the LED ring depicted is NOT the 60 element ring, but I think the idea is pretty clear.

Following the instructions from Adafruit, solder together the 4 Neopixel 1/4-ring pieces into a single ring. http://www.adafruit.com/products/1768. I'll just re-emphasize some of the more salient parts of this. While you DO want all four joints of your ring to have the 5V and ground connections soldered, make sure you DON'T solder together the data pads of the final joint -- you only want that data signal going in one side. I chose to have my power, ground, and data wires all leading off the same joint. I don't think it's necessary, but it looks cleaner to me.

After assembling the ring, it's a good idea to connect your ring to the Arduino and fire up a sketch to exercise the ring. You want to be sure that all the LEDs light as expected, otherwise when stuff doesn't work later you won't know if it's your hardware or your software. That's no fun. Your pre-requisite task for this is to have downloaded and installed the Arduino IDE and downloaded the Neopixel libraries from Adafruit, available on GitHub. There are plenty of tutorials available to walk you through how to use this software, so I won't bother here.  I discovered when I first ran the example sketches that only half my ring lit up, with a couple of odd LEDs here and there turned on for the remainder of the ring. Turns out I had a cold solder joint on the data pads between the second and third rings, so signal wasn't making it through. Better to find these problems now than later!

Some additional notes: I also followed the precautions noted by Adafruit to place a large capacitor across the power supply and put a small resistor inline with the data connection. They know more than me about electronics, so I did it. It works.

Your next step is assemble the WiFi shield, which is nothing more than soldering on the headers so you can attach the shield to the Arduino. As with the ring, I fired up example sketches to be sure that the WiFi shield was working properly. Below is a pic showing the wired up hardware with a trivial Aruduino sketch lighting up the ring with simple colors.



At this point, we have hardware. At the end of this series of posts, I'll provide a complete parts list for what's been built. Now we're ready to write some code to make the hardware do something...

WeatherClock - Part 1

This is first in a series of posts detailing the build and programming for what I'm calling a "Weather Clock." The folks at AccuWeather have nice mobile app that includes a real-time, minute-by-minute forecast of precipitation for the next two hours. What's neat about this is the visualization. They present a ring, with "right now" at the top and the minutes flowing along clockwise, just a like a -- well -- a clock. Each minute on the clock face is colored to represent the type and intensity of precipitation expected for the next two hours. Here's a picture, showing light rain starting in about 26 minutes, heavier rain around 90.



I always liked this visual, and thought it would be fun to build one of these weather clocks and hang it on a wall. You could certainly do this mostly/entirely in software by building an app to run on a tablet, then hang the tablet on the wall. But in this case I wanted to tinker around with actually building dedicated hardware. Like many people drawn to building internet-connected devices, my background is in software -- not hardware -- so I approached this project with a little trepidation. Turns out there wasn't much to fear, this came together pretty well (I think). By the end of this series of posts, I'll have provided links to everything -- the hardware components, the code, etc. I welcome any and all comments about how this could've been done better, or differently, or whatever.