Out-of-control Azaleas

It’s azalea-pruning time of year again. I’ve got a multi-year project going to tame the two huge azaleas outside our living room window. They were neglected for a long time and have gotten very leggy, woody and overgrown. One of them is actually two azalea bushes that have grown together. The big ones are way too big for their britches — that is, aesthetically, they don’t work well right alongside the house. I’d love to transplant them somewhere they can bush out to their hearts’ content. Then, I’ll get some more little dwarf azaleas to plant next to the house. The U.S. National Arboretum has a very informative Azalea FAQ page. An excerpt:

Azaleas have very shallow root systems, so even large azaleas may be successfully transplanted. It is important to dig a wide root ball. Don’t worry about digging deep into the soil since most azalea roots are near the surface. The best time to do this is early spring or early fall when the weather is cool. Begin by preparing the new planting site. Then dig the azalea, preserving a root ball as wide as can be safely moved. You can lift it onto a tarp and then use the tarp to drag the plant to its new location rather than picking it up. Be sure not to plant the azalea too deeply and water it thoroughly after transplanting.

So it seems like it should be doable. Maybe I can put it on the plate for this Fall.

More on Ademco Keyfobs

We’ve been using keyfobs with our security system for a couple weeks now, which is enough to get a good feel for how they work. First off, the reliability is a lot better since I relocated the panel’s wireless receiver about 40 feet closer to the garage door area. I have a feeling that the house’s aluminum siding was interfering with reception in the receiver’s old location.

Currently, I have the fobs programmed to arm/disarm totally independently from the garage door opener. That is, two keypresses are required when either coming or going: One to arm/disarm the system, and another to open/close the garage door. This has proven to be a little inconvenient, particularly when arming/closing/leaving. This particular process would be a lot smoother if I could get the “arm” button to shut the garage door as well as arming the system. I’ve come up with a tentative plan to accomplish that, if it works.

[More:]

First things first: For this to work, the garage door needs to be set up as what Ademco calls a “vent” zone. With a vent zone, the system can be armed while the zone is faulted (i.e. the garage door is still open). Then, when the zone is restored, it is automatically armed. To set this up on my panel, I had to define a custom zone type for the garage door. See your panel docs for details.

With that out of the way, the plan is to use two dry-contact relays (these are provided by the panel as on-board triggers, as well as by zone expanders and add-on relay boards):

  1. Wire the two relays in series (connect N.O. terminal from relay #1 to C terminal on relay #2)
  2. Connect C terminal from relay #1 and N.O. terminal from relay #2 to the terminals on the garage door opener
  3. Program relay #1 to activate (close) when garage door zone is faulted and open when zone is restored
  4. Program relay #2 to close for 2 seconds when “Arm” button on keyfob is pressed
  5. Program both relays to close for 2 seconds when “Door” button on keyfob is pressed

Explanation: The garage door operation is controlled by shorting two terminals together. If you do this when the door is closed, it opens, and vice-versa. With this method, we have no idea what state the door is in. So, we can’t use a single relay and just blindly close the contacts when arming. Otherwise, if we armed when the door was already closed, it would open, which we obviously don’t want.

To get around this, we need some way to tell whether the door is open or closed. That’s where the garage door’s zone comes in. We assume that if the zone is faulted, the door is open, and if not faulted, the door is closed. So, wire two relays in series, so that when both are closed, the door triggers. Then program one to close only when the garage door is open (faulted), and the other one to close when the “Arm” button is pressed. So when arming with the fob, the door is only triggered if it’s already open. This should work reliably almost all the time; the door can occasionally get into a half-open state where the zone will be faulted but the door will open when tripped. But, this doesn’t happen all that often, and just tripping it again will close it.

For the “door” button, which triggers the door regardless of its state, we just program both relays to momentarily close. This unconditionally triggers the door. Only one potential “gotcha” here: I’m not sure what the panel will do if a relay is already activated and we send it another signal to momentarily close the relay. We need it to keep the relay activated. If it doesn’t, there’s a chance that the zone-activated relay could end up open at the wrong time, and the “Arm” button then wouldn’t close the door as expected. In this case, we’d need to add a third relay in parallel with the opener, to handle the “door” button. But I’m hoping that won’t be necessary.

What about disarming, you ask? Can we get the system to disarm automatically when the door is opened via the keyfob? Well, here’s the deal. When arming, you always want to close the garage door. However, the inverse is not always true: You might want to disarm the system without opening the garage door. So, for now, I’ve chosen to leave this as a two-step process. I may rethink it down the road.

5/18: I’ve been kinda busy to do much with this the past 2 days, but this morning I got around to doing a brief proof-of-concept, to see if the panel could activate two relays simultaneously. I currently have a keypad function key programmed to trigger the garage door opener. There are two steps necessary to set this up:

  1. Program the function key for “Device Activation” (*57)
  2. Program an output action (*80), triggered by “zone type” 66 (function key), which closes the garage door’s relay for 2 seconds when triggered.

To do my test, I just added an additional output action to turn an X10 light on/off with the same function key trigger (zone type 66). It worked — when I pressed the function key, the garage door opened and the X10 light turned on at the same time. That bodes well for this project; I should be able to do it with 2 relays and a bare minimum of wiring. Stay tuned!

5/19: Work on this continues at a glacial but steady pace. Today I identified the relay wires on the zone expander and verified that the relay is working, by programming a function key to toggle the relay and then checking the resistance between the C and N.O. wires. Wire IDs are as follows. Relay 1: C – Brown; N.O. – Yellow. Relay 2: C – Violet; N.O. – White. To wire in series: Splice yellow to violet, and connect brown and white to garage door opener terminals.

5/21: Wired the relays up in series this morning, and everything seems to work fine. Assuming there are no problems, the only thing left to do is solder the splices and clean up all my wiring. Then it’s done!

For programming… since I have a lot of keyfob zones that need to trip various garage door relays, I decided to create two zone lists (*81) for zones that trip relay #1 and #2, respectively. That saves me from defining identical output functions for each individual button zone. It seems to work well that way.

SSN Remediation: One Step Closer

We’re one step closer to the happy world of SSN Remediation. Our development SIS database is now using the HP-ID, which is the new primary key we’ve designated to replace the SSN in SIS. HP-IDs look distinctly familiar: They’re 9-digit numbers just like SSNs. That way, we cleverly avoid having to rewrite most of the SIS code to deal with the new IDs.

On the myUMBC side of things, I just need to change the code to look for the HP-ID LDAP attribute, instead of socialSecurityNumber. Which brings up a temporary problem: HP-IDs aren’t in LDAP yet. So how do I look them up? Well, right now, I’m still querying the SSN in LDAP, then bouncing that against a super-top-secret SSN-to-HP-ID translation table in SIS. That does the job nicely for testing purposes, but I must stress that it’s only a temporary measure.

Next up, I’m doing some hacking on the class list code in the Perl myUMBC codebase, to add in some new features (part of the big drive to improve student retention rates). I’m looking at the class list code, and I’m thinking I could really speed it up if I changed it to use prepared statements with bind variables, but the code is oh-so not set up for that. I may take a closer look at it tomorrow to see how hard it would be to do.

[More:]

The class list code, as it currently is, works like this:

foreach ( student in the class )
   create perl object with student info
   tell perl object to fetch info from DB
   display student info in table
end

The student info object it creates, has all of the SQL necessary to pull the student’s data out of SIS. It’s doing this stuff over and over, which is where we could benefit from prepared statements. To do it, though, we’d need to create the prepared statements ahead of time (outside the loop), then pass them to each student object that we create. I don’t think it’d be really hard to do, just need to figure out the best way to do it.

Followup… tried this out, seems to work. The challenge is going to be figuring out where to create all the prepared statements, and how to manage them, without obfuscating the code even more than it already is. Seems like it might make sense to do it as part of the db_connect and db_disconnect routines… will mess with it more tomorrow.

Actually, I think I’ll go with a slight variation on that theme. Rather than creating all the prepared statements when I connect, I’ll modify my db_prepare routine to maintain a hash of statement handles. The first time it handles a particular statement, it’ll prepare it and cache the statement handle. Then on subsequent calls, it’ll just retrieve the previously cached handle. When I disconnect, I’ll just walk through the hash and call finish on all of them. Should work great, with a minimum amount of surgery on the code.

Saturday’s Hijinks

Another fun Saturday around the house…

First up: The security system. I finally got around to relocating the wireless receiver to try to get better performance out of our new keyfobs. At the same time, I installed the status transmitter module so the keyfobs can receive status information. So far, things look good. the status transmitter seems to work fine, and there seem to be no issues with the window transmitter in the master bathroom. I had some concerns that this one would have problems because of the distance from the receiver. But, it works fine. Next up.. we’ll see how things work like this for a week or so, and if everything looks good, I’ll clean up the wiring, reattach the sirens, replace the battery and stick a fork in this one.

Next up: The pool. With t-minus one week until we uncover it, I decided I should take a look at it. I’ve had other stuff keeping me busy, so I’ve kinda neglected it for the past month or so. As I feared, it’s a nice green swamp. Anyways, to get a start on cleaning it up, I started the pump and siphoned in 5 gallons of 12% hypochlorite. We’ll see how it looks tomorrow.

[More:]

This year, rather than adding chlorine through the skimmer, I think I’ll pour (or siphon) it into the shallow end in front of a return jet. That should disperse it pretty efficiently, and it should also be easier on the pump and filter. Siphoning is a little slower than pouring the stuff in directly, but it avoids splashing, which is a big plus.

The fun never ends..

Followup 5/15.. the 5 gallons of chlorine cleared it right up and left a chlorine residual, but the pH is high now (8.2). Dunno what the alkalinity is, but I’m sure it’s low. Not sure which I should adjust first.

Howard County, MD property tax installments

Background: My home county bills my property tax in two semiannual installments. The first installment is always larger than the second installment. But I’ve never been able to ascertain the formula they use for figuring the amount of the first installment vs. the second installment. The other day I spent a half hour or so playing with the amounts, and couldn’t figure out how they were arriving at the numbers.

Today, I finally found the magic formula on Howard County’s web site. It’s not particularly easy to find stuff on their site: I dunno if it’s because it’s badly laid out, or if it’s just that I tend to look for obscure info that the webmasters don’t see fit to post prominently. But regardless, it seems like when I need to find something there, I have about a 50% success rate, and the info is never where I expect to find it. But I digress.

From the Howard County Property Tax FAQ:

Under the semi-annual payment schedule, the first installment consisting of one-half of County, State, Fire, Ad Valorem, Mid-Patuxent levies and the full amount of Front Foot and Trash Fees is due by September 30th. The second installment consisting of the other half of the levies is due December 31st.

So there you have it.

[More:]

So why do I care about this? Being a self-professed financial geek, I like to project future bills as far in advance as possible. I’ve already figured out how to compute my total property tax bill for a given year. And since I’m stuck with an escrow account on my current mortgage, I’ve also figured out the formula my mortgage company uses to do escrow analysis. If I can project my property tax installment schedule, I can do a full projected escrow analysis for the current year, and figure out what my monthly mortgage payment will be next year (and whether I’ll be getting a refund check).

Sometimes I wonder if I’m in the wrong field..

6/16: Well, I found out my tax bill for 2006 (haven’t gotten the mailing yet, but it’s online at Howard County’s Property Tax Lookup page), and, it’s within a penny of the amount I predicted. OK OK, you can stop applauding now. Our ever-escalating assessments are keeping the bill on a steady rise, but this year’s increase was the smallest in the past 4 years, thanks to token cuts in the tax rates by both the county and the state. That, combined with the homestead exemptions, is keeping the bill from bankrupting us, but it’s still going up faster than the rate of inflation (and is pretty much guaranteed to keep doing so for the next several years). We need to pressure our elected officials to keep nudging the tax rates down to compensate. That’s the way it’s supposed to work.

Not-So-Flexible Spending Accounts

Between my wife’s broken foot and my son’s infection, I’ve spent quite a bit of time in doctors’ offices this past week. This week, we have doctor’s appointments every day except Friday. Next week, we have appointments Monday and Tuesday. Every visit means another co-pay. We’ve got a pre-tax health care spending account (HCSA), but we depleted it ages ago. Every year I sign up for the account, I worry that I might be putting too much into it. Every year, I end up wishing I had put more in. Which brings me to my gripe of the day. Now, don’t get me wrong. I love HCSAs. My employer calls them “Flexible Spending Accounts”. The problem is, they’re really not that flexible at all.

[More:]

Here’s the way our plan works: During annual open enrollment, if I choose to enroll in a HCSA, I have to choose a dollar amount to contribute to the plan every pay period. Then, for the next year, that amount is deducted from each paycheck before taxes, to fund the HCSA. Then each time I have a medical expense not covered by insurance (like a co-pay), I can request to be reimbursed for that expense from funds in the HCSA. Thus, I can pay for these expenses with tax-free dollars. One of the great features of these accounts, is that I can request funds from the account before I’ve actually made the contributions — which in effect is an interest-free loan.

So why am I griping? Well, the problem lies with the amount I choose to contribute, and the fact that I can’t change that amount during the course of the year. At the beginning of the plan year, I have to estimate the year’s medical expenses, and choose the amount based on that. But, I can’t predict the future. So, I estimate conservatively, to avoid losing the funds in the account.

I’d really like to see the rules for HCSAs relaxed a bit, to allow participants to make changes to the contribution amount over the course of the year. I think it would encourage more people to take advantage of them. I’m sure there’s some reason they don’t work like this (administrative overhead comes to mind), but if they did, it would certainly almost always work out to my advantage, at the expense of Uncle Sam. And suddenly it all becomes very clear..

A bit of everything today

I skipped work today so I could ferry the clan around on various errands, and seized the opportunity to knock a few odd things off the to-do list.

First off, I paid my first visit to Namco, my favorite place to get pool supplies. The prices have gone up this year, which comes as absolutely no surprise to me. But, they’re still pretty much the cheapest place around for chemicals, particularly after late August when they blow everything out at half price (which really drives home how high the dealer markup is on pool chemicals). I bought a couple 5-gallon jugs of liquid chlorine, which is basically sodium hypochlorite (household bleach) at about twice the strength of grocery store bleach. Namco has this stuff at $13 for 5 gallons, plus a $6 deposit for the jug. That’s a decent price, and it makes me wonder how much of a premium I’d pay to use this stuff instead of calcium hypochlorite for daily chlorination. The main advantage of cal-hypo is its shelf life: I can buy it at half price late in the season, and it’ll still be just as potent the following spring. Its drawback is inconvenience. To avoid clouding the pool water, you need to dissolve the cal-hypo in a pail of water, then pour it off. Then you have a lot of sediment left over that you have to get rid of. The liquid chlorine is much more convenient, but its shelf life is shorter, so I’d need to buy it at full price during the season. The challenge here is to figure out the true effectiveness of the cal-hypo vs the liquid stuff, then see how much of a premium I’d pay for the liquid stuff, and determine if the convenience is worth the price difference. I love doing this kinda stuff, so you can be sure I’ll tackle that soon..

In other news, we got our vegetable garden planted. To keep the critters at bay, we strung chicken wire around the garden and hung some old CDs above it. The theory is that the CDs will blow around and flash as they catch the light, which discourages birds. We’ll see how it does this year. I guess the next step would be to add lawn edging to prevent moles/groundhogs/etc.

… and finally, I made a stab at speeding my wife’s anemic Windows XP box up a bit. Basically I went into the Microsoft System Configuration utility (Start Menu -> Run -> enter msconfig), went to the “startup” tab, and disabled a whole bunch of unnecessary kruft that the OS was starting up at boot time. It’s amazing the amount of junk that accumulates there over time.. Quicktime crap, Adobe crap, crap from some kid’s software we installed, crap from Dell, crap from the stupid stuff that Dell pre-installs on the computer, AOL crap, the list goes on and on. After I turned a bunch of stuff off, I rebooted and the machine seemed a good deal snappier. I guess we’ll see how it goes from here.

Maryland’s 529 Plan

I’m getting ready to open a new college savings account for our new son, Andrew. This time around, I’ve decided to go with a 529, the Maryland College Savings Plan. For our older son, I have a Coverdell Education Savings Account. I’ve always been partial to the Coverdell accounts, mainly because I like freedom — I can open a Coverdell with my favorite brokerage, and invest in pretty much anything I can invest in via a regular brokerage account. On the other hand, most 529 accounts tend to be more like annuities or 401(k) type plans: you are limited to a fixed set of mutual funds or mutual-fund type investments, depending on the plan. Of course, you’re free to choose any 529 plan out there, but if you want to take advantage of the tax benefits 529s offer, you typically have to pick the plan from your home state.

I like Coverdells because of their flexibility, but they’re not perfect. For one thing, the annual contribution limit is a relatively low $2000. 529s typically have a much higher limit, and with Maryland’s plan in particular, I can deduct contributions up to $2500 from my Maryland state income taxes. It was this little perk that sold me on the plan. The plan does charge a one-time $75 enrollment fee, but with the tax savings, I easily make that up in the first year.

As far as the investment choices go, they’re limited, which is a drawback. But, the plan is administered by T. Rowe Price, a very reputable mutual fund company. I’m even going to break with my control-freak tradition, and try out one of the “life cycle” type funds.

Post-setting indoctrination

I set a 4×4 post today, complete with concrete footing. While this may not seem like much, it was a big deal for me as I’d never done it before. My parting impression: it’s a lot of work. Between digging the hole and handling the concrete, it’s quite the back breaker.

To dig the hole, I used a garden variety post-hole digger. I can see why people recommend a power auger if you’re doing a lot of these… it’s slow going. And of course, by Murphy’s law, about 1 foot down I hit a giant rock (several giant rocks, actually). I was able to break them up pretty easily with my ball-peen hammer and a cold chisel, but it certainly added some additional sweat equity to the job. An air chisel or demo hammer would probably make this a bit more fun.

I wanted to get the hole about 2-1/2 feet deep, but I stopped a couple inches short because I hit a giant root, and I made the executive decision that the hole was deep enough. Then I dumped in some gravel, followed by a few inches of concrete for the footing. Then I stuck the post in, plumbed it and staked it up, and backfilled the hole with concrete. It sounds easy, but it was a lot of work, especially since I was mixing the concrete by hand. The concrete is still curing, and hopefully once it’s done the post will be pretty bulletproof.

Incidentally, the purpose of the post is to support…. a bird feeder. Yep, a 4×4 with concrete footing is probably way overkill for a bird feeder, but it was a worthwhile exercise nonetheless. I may be doing the same thing for our mailbox one of these days.. the mailbox and post have both seen better days.

Sorting Tables with Javascript

I just wanted to take a minute to plug Standardista Table Sorting, a nifty set of Javascript routines that automagically sorts rows in HTML tables. I was recently asked to add row sorting to myUMBC’s class list function, and my first thought was to do it in Javascript, which would give the end user instant results as well as reducing server and database overhead — a double win. I started out writing something myself, then decided to poke around and see if someone had already written something. I found the Standardista stuff, and it works great.

[More:]

Getting this working was fairly straightforward. I had to modify myUMBC’s Perl HTML ‘table’ object so that it sets the headings apart from the body with <thead> and <tbody> tags. Then, I just added <script> blocks to pull in the Standardista Javascript code, and gave my tables the sortable class.

At first, it didn’t work. It turns out the Standardista stuff doesn’t like any additional markup (text decoration, font tags, etc) within the heading tags. Once I got rid of the markup, it worked.

I also had to fiddle a bit to get the sorting to play nicely with my striped rows (alternating white and light gray). The Standardista code includes support for striping, but I had to change the way I was applying CSS to my table (move the class attribute from the <td> elements to the <tr> elements), and I also tweaked the Standardista code to use my CSS attribute (myumbcLightGray) instead of its own (odd). With uPortal, I have to be sensitive to CSS namespace collision issues, and odd was a bit too generic. Once I made these adjustments, my striping was preserved after sorting.

This is a really cool package and I highly recommend it for any table-sorting application.