Spring has come and so has yummy cauliflowers!
I recently finished the first phase of my solar hot water project and now get most of my domestic hot water from the sun. Good times!
I followed the plan from BuildItSolar $1000 Solar Water Heater, modified to suit my situation and needs.
I wanted to do radiant floor heating on my ground floor so I have about 3 times the square footage of collector and a larger storage tank.
I built one panel almost exactly like the one from BuildItSolar, then while searching for keep copper pipe on craigslist (tip: do a search then click the rss icon in your url bar, which adds a rss feed of the search results to your feed reader or email client, at which point you see all the new results as they come in) and I found someone selling an old school set of commercial collectors. There were three, 3′x8′, metal and glass collectors, model Colt Inc. C-141C (only identification on them) that were being used to heat an old hot tub. Anyway the seller claimed they worked fine and didn’t leak – so at $200 bucks it was a good deal for me. The three 3×8 panels give 72 sf and the 4×8 I built gives 32 sf, so I nominally have 104 sf of collector area.
Mounting the Collector
The collector is mounted on my carport roof. 4 pads of pressure treated 2×6 where put onto the roof with roofing compound and appropriately long lag bolts into the supporting beams of the roof. A 4×4 was run from one end to the other as the base. For my home built collector with it’s wooden frame I just used gate hinges to attach it to the 4×4 (replacing one of the screws with a lag bolt for extra support) The commercial collectors came on a piece of angle bar with some hinges that we managed to get to work with some slight fiddling. I didn’t actually solder the three commercial collectors together, instead I spaced them apart by 8 inches and used hotwater discharge hose and hose clamps between them (with a little silicon caulk between the hose and the metal) so that if the collectors did have issues, or if I need to re-roof or do work up there it will be much easier to move the collectors. (Thus far it is working fine, zero leaks, but I’ll see how they hold up) To raise the collectors up and down we came up with a cool solution of using 4 scaffold jacks with swivel bases. The top end of the collectors are attached to a 4×4, and from there on each a scaffold jack has it’s base lag bolted to the 4×4 and the screw portion hangs down. On the mounting pad another scaffold jack is attached with the screw portion pointing up – a piece of appropriately heavy pipe is put between them. Each scaffold jack gives 18″ worth of movement, so total there is three feet worth of extension and all you have to do is turn the adjustment screws. Worked out quite well and is easy to move up and down (though you have alternate legs every few inches of adjustment so as to not get things to cockeyed)
The tank is similar to the BuiltItSolar $1k tank, but a bit larger and I doubled up the 2x4s both top and bottom. Used nail plates and several large nails through them. For the lid I have tank liner, then 2″ insulation (which extends out over the 2×4) then 1/2″ plywood. When I put in the tank insulation I made sure that it stuck up ever so slightly above the top of the tank, with the idea that that lid would rest on that – then I used long coated deck screws to tighten the lid down onto the tank, which seemed to cinch everything together nice and tight. For the piping going into the tank I had it go between the lid and the tank edge insulation – I marked where it would be going through on the lid edge, then took off the lid and smashed the insulation down with a hammer, which just gave the piping enough space to fit in there (with the appropriate use of clamps and deck screws) so it seems like a real tight fit. Nominally the exterior is 56″ x 48″ and this leads to a total of 213 gallons of storage capacity. I also put 3″ foam I had laying around on the top of the lid and some of the left over 2″ foam around the sides of the tank.
The main heat exchanger is a 300′ loop of 1″ PEX, connected to the water system with CPVC for abut 6 feet of valves and elbows then to the copper line with sharkbite. I did it that way to minimize install time as working with CPVC is really extremely easy vs trying to solder under the house up next to the joists and vents, etc. I initially had the tie in come down from the ceiling and go in / out of the tank, but I noticed that at least on the outlet site I was leaking heat up the pipe pretty far, so I changed it so the tie in comes down from the ceiling to below the waterline in the tank then backup, this seems to prevent any convection from sending heat up the pipes. I used a Wilo Star S 21BFX pump which seems to work well on the middle pump setting. (The system has fairly high head as the collectors are on the carport roof and pump and tank are under my house) I used CPVC for the runs to and from the collector, again for the ease of use. The outlet from the collector has about 15 feet of copper on it though. I transition from copper to the CPVC using discharge hose and pipe clamps so that there will be some flexibility in the system when I change the angle.
I used a Thermal Leak Detector to check how the tank was doing thermally (seemed good and at $34 bucks those are handy to have around.)
For tank monitoring I have a La Crosse weather station, for which you can by an optional wireless sensor which includes a probe that will do up to 140 degrees F. I dropped that in the tank and now I can tell you exactly what the tank temp is up in my office (114.6 after several partially cloudy and cloudy days.) I actually have my tank set to 150F, so it just stops at 140, but it’s good enough for me, as most of the time I use enough of the tank heat to keep it under 140.
The system seems to ‘flap’ a bit, where it will turn on to heat for a few minutes, then turn off, then a few minutes later turn on again. If I had to guess I would say it has to do with sensor placement at the collector side, but I haven’t had a chance to play around with it yet.
There is a slight plastic smell to the water from the shower, seems to be slowly fading over time but it was a little annoying to me (my wife didn’t seem to notice) I don’t know if that is the 300′ PEX, or the short run of CPVC and CPVC glue.
Still have the radiant heat flooring to put in. I have all the pieces for that, just need to find some time this summer to do it. I guess my one slight concern is the pump I have for it is a cheap iron circulation pump, and I was wondering if that will cause any problems other than just not lasting super long. Guess I should hit up the internet and work that out.
Just in time for the debates, have yourself a chuckle at palinvoodoo.com’s Sarah Palin Voodoo doll.
Speaking of politics, I really need to stop watching the news because the GOP’s general horribleness frightens and angers me to no end.
Whirled is just what it sounds like,
an online “world” har har – oh my side! Written in Flash, and thus
very accessible from all the major browsers and computer platforms.
Part casual gaming, part social networking, part creators pallet -
it is really quit unique and has an array of wildly different things
to do. I personally was highly entertained by a little game called
“Corpse Craft” whose game play is described as: “Build an army of
re-animated corpses to destroy your foes in this puzzle-action
hybrid.” Which is quite apt. The art is great, the story and
game play entertaining. You play a game of ‘implode’ or ‘collapse’
or whatever else you want to call it on the bottom of the screen.
As you destroy groups of similarly colored blocks you increase the
number of resource blocks of the same color. You spend those
resources to launch different types of re-animated corpses across the
screen. The different corpses have different abilities that you are
trying to use to destroy your opponents corpse re-animation factory
on the other side of the screen, who of course is sending re-animated
corpses to try and destroy you. It starts off quit easy and gets
much harder for the last few levels. Regardless quite fun and
doesn’t take ages to get through.
So I did the Marin Century ride today, which was quite an event. The
longest ride I had done before was 45 miles up to the top of Mount
Tam, so this was a change! Mostly it is just a long time to be
riding a bike. There are several large hills on the route as you
can see on
and there was a bit of a cross wind and head wind from time to time.
But, overall the weather was quite good. Sunny with a cool breeze
most of the day as we were near the coast. The early morning views
of valleys with clinging pieces of fog were classically Californian
coast. There were 4 rest stops on the route, all with lots of good
food and drink and restrooms. I had lunch part 1 at the second rest
stop and lunch part 2 at the third rest stop. After about 60 miles
my ass was starting to hurt – not surprisingly it continued to hurt
more for the rest of the ride. My left calf threatened cramp up but
never did. My right knee got a bit twingy after 80 miles and around
95 started to hurt if I put much force on it, so I mostly used my
left leg to get me up the last big hill then coasted the rest of the
way in. I thought it was interesting that I wasn’t really slowed
down by my cardio or my length strength but more due to the rest of
me wearing out. That is to be expected I think since I didn’t build
up slowly to a 100 miles. The book The Complete Book
of Long-Distance Cycling was pretty handy tool for figuring out
what I needed to do to train, but I only had 6 weeks and there is
only so much one can do. Oh and my right big toe had the outside
edge go numb, but it’s done that ever since that fateful backpacking
trip in ’98 so I was expecting it. I wore a lot of sunscreen but
got a little bit burned on the back of my calves as the sun shifted
around. I also had some king of bug fly into my shirt and get
caught which involved me then pulling over and frantically trying to
let said bug out as I could hear it buzzing around under my jersey.
Eventually I got it to fly out of my sleeve! The total route was
106 miles with 6250′ of elevation. From start to finish was about 9
hours for me. I was on my bike for 7 hours and 15 minutes, so
lunch, rest stops, and bug removal definitely took up some time. My
average speed was 14.3 MPH while I was on my bike. Definitely nice
that they had a good spread of food when I finished (including free
hagen-daz ice cream!) I certainly slept well that night.
So I was trying to set up some data to go into a partitioned table in postgres and given our architecture relies on hibernate I thought it would be nice to be able to be consistent and use hibernate to push the data into the partition and read it out. I also wanted the partitioning table creation to be handled more or less automatically.
Setting up the partitioning in postgres was fairly easy. I created the master table FOO and an insert trigger on foo that calls a pl/pgsql function insert_foo. The FOO table is partitioned by date, so in insert_foo I take the date of the record to be inserted (NEW.datecreated) and use that to build up the name of the partition table I really want to insert it in: FOO_082008. I then use that table name an build a string that contains an insert command (carefully using quote_literal on the values to be safe) and EXECUTE that command. I catch the undefined_table exception which is thrown when the date rolls over to a new month for which we don’t yet have a table. In the exception handling code I dynamically create the table and rerun the original dynamic insert.
This actually all works quite well. The problem is hibernate, or more specificly hibernate helpfully trying to check for errors for you. Basically when you tell hibernate to save a Foo object it runs the insert on FOO. The trigger catches that and instead inserts the data into FOO_MMYYYY and returns null so no further processing by the database is done and the jdbc driver returns saying it inserted zero rows into the FOO table, which is technically true, and hibernate freaks out because it is expecting that 1 row should have been saved. That is reasonable enough, but annoyingly there is no way to tell hibernate you really expect zero rows. The exception that is thrown is a fairly generic HibernateException, so the only way to catch and swallow this one particular case would be to text match on the error message. We all know what a terrible idea that is, so we are a little SOL.
There are two things that seem like they would work with hibernate. One, is to use a postgres RULE instead of a pl/pgsql FUNCTION to do the partitioning. RULEs basically rewrites the sql you are going to run, so from the jdbc driver point of view you should get back that you did, in fact, save 1 row to FOO_MMYYYY. However I’ve never used rules and from what I can gather from my checking out the less that totally awesome documentation on the subject, it doesn’t seem like I can do the same level of magic table creation. You would have to maintain the rule so that each month you added a new if/then check to save the data to the appropriate table for the month and create the new table for the month. Even if you did that once a year and pre-created a years worth of tables it is still maintenance and someone could still screw it up. (Quite easily given my experience with DBAs The other option is fairly hacky but does work. If insert_foo returns NEW instead of NULL then the insert operation continues just like before the trigger was activated and the jdbc driver reports 1 row saved and hibernate is happy. Of course the problem is that we now have one copy of the data in FOO and one in FOO_MMYYYY, that’s no good as all FOO_MMYYYY table inherit from FOO so all queries on FOO will return duplicate results. So to get around that you can make a table FOO_IN that is the same definition of FOO. In the hibernate mapping you map FooIn to FOO_IN and add a trigger on FOO_IN to call insert_foo. You modify insert_foo to return NEW and to delete from FOO_IN, this all results in a copy of the data going into FOO_MMYYYY and another going into FOO_IN, which is deleted the next time anything is inserted. Of course you can’t use hibernate to read from FOO_IN since there is nothing there. So you create another mapping for a class FOO_OUT that is the same as FOO_IN but maps to the table FOO. This is a little redundant but you only have to do it once. You can make FooIn and FooOut inherit from FooBase and use that in places the data could be read in or out.
If there were someway to do a DELETE in postgres that doesn’t cascade to the child tables you could get away with one mapping and insert_foo could return NEW and also delete from the FOO table. That is a little problematic as you would always have 1 duplicate row in the master table, but I can’t figure out how to actually do that, so it isn’t much of an issue.
Of course depending on what you are doing you can also use straight sql, but kind of annoying to do the whole mix and match with database. Anyway maybe there is a better way but I couldn’t work it out after a day of poking around.
Here is an example of using date to do the partitioning in a postgres pl function:
CREATE OR REPLACE FUNCTION dw_foo_insert_trigger()
RETURNS TRIGGER AS $$
dateTable := ‘foo_’ || to_char(NEW.transaction_date, ‘MMYYYY’);
— you could also probably do NEW.* if you don’t care about column order changing.
cmd := ‘INSERT INTO ‘ || foo || ‘(id, code, transaction_date, override_id, product_code)’ ||
‘ VALUES (‘ || quote_literal(NEW.id) || ‘,’ ||
quote_literal(NEW.code) || ‘,’ ||
quote_literal(NEW.transaction_date) || ‘,’ ||
quote_literal(NEW.override_id) || ‘,’;
— join strings together with null values results in a fail, so check for those explicitly
IF (NEW.product_code IS NULL) THEN
cmd := cmd || ‘null’ || ‘,’;
cmd := cmd || quote_literal(NEW.product_code) || ‘,’;
WHEN undefined_table THEN
— creat the new child table from the parent
createTable := ‘CREATE TABLE ‘ || dateTable || ‘( ‘ ||
‘CHECK ( transaction_date >= DATE ”’ || to_char(date_trunc(‘month’, NEW.transaction_date ), ‘YYYY-MM-DD’) ||
”’ AND transaction_date < DATE ”’ || to_char(date_trunc(‘month’, NEW.transaction_date + interval ’1 month’), ‘YYYY-MM-DD’) ||
”’)) INHERITS (foo)’;
— create the index on the child table
createIdxTUID := ‘CREATE INDEX IDX_’ || dateTable || ‘_ID ON ‘ || dateTable || ‘(id)’;
— and rerun the command now that the child table exists
CREATE TRIGGER dw_foo_trigger
BEFORE INSERT ON foo
FOR EACH ROW EXECUTE PROCEDURE dw_foo_insert_trigger();
Hibernate In Action Is a pretty good reference for Hibernate and PostgreSQL Developers Library is one I want to get for postgres at some point in the future.
Jake and I entered the 2008 Pacific Cost Brew off with a batch of American Brown Ale we had made about a month ago. The contest was held today, and while we didn’t win anything it was a great time. Not to mention we got free t-shirts, tasting glasses, and the opportunity to try a variety of good beers. We are definitely at the low end of the brewers with our very lax production schedule, bottling instead of kegging, and doing partial mash instead of all grain. A couple of brewers had 7+ entries in kegs which was pretty impressive. Everyone was essentially an enthusiast and were all very supportive and encouraging of each others efforts. The contest was held in Potrero Hill, with tables for the brewers, a couple of tents, a DJ, and surprisingly cooperative weather. We drove over around 12:30 to set up our booth and taste the other entries before the general public started in on them. Molly had made cookies as palate cleansers / bribes and Jake had made a nice label for our bottles so our table area looked pretty good, almost professional one might say. Poured beer till we ran out around 4:30 and the results were announced at 5. Definitely a good experience and hopefully one that we will repeat in the future.
A good day for all. We started letting the cats explore the deck with supervision and Chufi finally found the catnip plant. He was extremely, EXTREMELY, interested. Rachel and I had a nice dinner sitting out on our deck watching the sky change color and get more and more dramatic. Can’t beat good food, company, a glass of wine, and an amazing sunset. The pictures speak for themselves I think.
A number of you have been wondering what our place looks like, so at long last I have pictures of a more or less clean apartment. The summary is we are on the bottom floor of a duplex built out over a canyon. It is an 800sf 1 bedroom, with a walk in closet and nice deck that is about 50 feet off the ground. Right in the trees for us!