Greg`s Tech blog

My technical journal where I record my challenges with Linux, open source SW, Tiki, PowerShell, Brewing beer, AD, LDAP and more...

Reset a Whirlpool Duet washer

Monday 06 of April, 2015
We accidentally started the washer with hot water feed turned off. When the washer tried to fill, it couldn't and generated F08 E01 error codes. After clearing the codes and restarting, we eventually got to a point where the panel wouldn't light up at all. Unplugging and re-plugging the power would do nothing except start the pump.
It was obvious it needed to be cleared. After too much searching, I found this link on forum.appliancepartspros.com (cache).

It tells you to press "Wash Temp", "Spin", "Soil" three times in a row to reset the washer. Once it resets, the original error will display. Press power once to clear it. After that - all was well (of course I turned on the water first)

Adjusting Brewing Water

Tuesday 10 of March, 2015
I recently got hold of (well, asked for and received) a water analysis from the Perkasie Borough Authority and have been staring at it for more than a month wondering what to do with it. I've read the section on water in Palmer's How To Brew and some of his Water book. These are both excellent resources and while I have a science background, they are quite technical and I've been unable to turn all the details into an action to take, if any, on my brewing water.

The March 2015 issue of Zymurgy (cache) has an article by Martin Brungard on Calcium and Magnesium that has helped me turn knowledge into action. At the risk of oversimplyfying the guidance, I want to draw some conclusions for my use.

Some of Martin's conclusions
  • A level of 50mg/L Calcium is a nice minimum for many beer styles
  • You may want less than 50mg/L for lagers (wish I knew that a week ago) but not lower than 20
  • A range of 10-20mg/L Magnesium is a safe bet for most beers
  • Yeast starters need magnesat the high end pf that range to facilitate yeast growth

The Water Authority rep who gave me the report said two wells feed water to our part of the borough. Looking at the two wells, the Ca and Mg values are similar averaging 85 mg/L and 25mg/L respectively.

This leaves my water right in the sweet spot for average beers styles. What about some of the edge cases like IPAs and lagers.

  • For lagers, next time I'll dilute the mash water with 50% reverse osmosis (RO) water to reduce the Ca to about 40. I may want to supplement the Mg to bring it back to 20.
  • For IPAs, I may want to add Mg to bring it up near 40 mg/L.

Building a Temperature Controller from an STC-1000

Sunday 04 of August, 2013
My son & I have been brewing beer together for 8 months now. We've been very intentional about moving slowly into the process of building both our knowledge and our brew system. As I'm already a tech geek, it is real easy for me to become a brewing geek as well and to go broke in the process. When we started collecting brewing equipment, I agreed to try to buy everything half price. Home Brew Findshas been invaluable when looking for the cheapest way to solve a brewing problem.
With the summer months and the need to lager a Dopplebock, I converted a 20 yr old dorm fridge into a fermentation fridge using 1.5" foam insulation.
Fermentation Fridge
Fermentation Fridge
And while this allowed me to lager, in this configuration it doesn't actually control the temperature so I went looking for a way to do that.
I settled the Elitech STC-1000 as it is a cheap alternative to the Johnson Controls controller (cache). Of course, the latter controller is a full package with power cord and power connectors for the cooling and heating units. The STC-1000 unit by contrast consists only of the controller and control panel. Oh, and it is Celsius only so you need to convert. But Google makes that easy ("convert 68 to celsius") My unit cost $35 to make while the Johnson is about $70.

To make use of the STC-1000, I had to build it into a package that allows for convenient use. Here's how I did it.

When I looked at the size of the STC-1000, it appeared the right size to fit in a standard outlet box (in the US and it was real close in size to the GFCI cutout. I bought a plastic cover to hold the GFCI and duplex outlet. I then modified to make the GFCI opening maybe 1/4" longer.

faceplate mod Mounted STC-1000

Next step was to mount the duplex outlet and wire it up. Keep in mind we need to control heating and cooling so we need to power the outlets individually. To do this, you have to break the copper tab on the black wire side of the outlet. I didn't take a before picture, but here it is after mod.
Outlet Modification

Now we can run a wire from the heating side to one outlet and from the cooling side to the other.

The other tricky piece is understanding that the STC-1000 only provides a relay service for activating the heating and cooling circuits - it doesn't actually supply power. I dealt with that by tapping the in-bound hot lead (black wire) to both the heating and cooling connectors. This is seen here with the first loop coming from the power in going to heating and the second loop from heating to cooling:
Outlet Modification

To power the outlet, I took a short wire from the heating to the outlet and from the cooling to the other outlet. The white wiring is pretty straight forward. Simply tap the in-bound white wire and connect it to one of the white lugs. No need for separate connections as the common wire is, um, common.
Finally, we add a tension-reliever to the box, run the temperature sensor through it, mount the outlet and buckle it up
tensioner Mounted STC-1000

- I used a new orange 25' extension cord for the power side. I cut it in half and used wire from the unused half to do the wiring. I then added a new plug to the remaining cord so I had a usable cord.
- The STC-1000 was $19, the extension cord - $10, the box and cover $6. So this controller cost $35 plus two hours labor.
- Here is a wiring diagram
Wiring Diagram

Using getElementByID in Powershell

Thursday 07 of March, 2013
I was asked to pull a piece of information from a web page using Powershell. Fortunately for me, the item is tagged by an html "ID" element. While testing I discovered the following code worked when I stepped through it line by line, but failed when run as a script.
(Note 1: The following is a public example, not my actual issue. This snippet returns the number vote total for the question)

$ie = new-object -com InternetExplorer.Application
$ie.Document.getElementByID('post-832-score')|select innertext

The code is straightforward. It creates a new COM object to runs Internet Explorer. navigates to a specific page, then looks for a specific "id" tag in the html and outputs the value. The problem we saw was when we attempted to run the $doc.getElementByID command we received an error saying it could not be run on a $null object.
The question was asked during the Philly PowerShell meeting that perhaps the script needed to wait for the $ie.Navigate command to complete before moving on. And indeed this appears to be an asynchronous command. That is, PowerShell executes it but doesn't wait for it to complete before moving on to the next command.

The solution was the addition of a single line of code:
while ($ie.Busy -eq $true) { Start-Sleep 1 }

It simply loops until $ie is no longer busy.

The revised script looks like this:
$ie = new-object -com InternetExplorer.Application
while ($ie.Busy -eq $true) { Start-Sleep 1 }
$ie.Document.getElementByID('post-832-score')|select innertext

Adding XCache for PHP on Fedora

Tuesday 26 of February, 2013
I want to run XCache on my Amahi server to help speed up some php apps. Details on adding it are found here (cache)
  • yum install php-devel
  • yum groupinstall 'Development Tools' (44 packages - yikes)
  • yum groupinstall 'Development Libraries' (78 packages)

cd /tmp
wget http://xcache.lighttpd.net/pub/Releases/3.0.1/xcache-3.0.1.tar.gz
tar xvfz xcache-3.0.1.tar.gz
cd xcache-3.0.1

./configure --enable-xcache
make install
(Note: I ran make test and one test failed "xcache_set/get test")

Our First Brew

Friday 28 of December, 2012
Priscilla, Kyle & I have been enjoying local craft beer recently. There are several local breweries (Free Will, Round Guys, Prism) and many pubs are now serving craft beer along with the mass market beer. It's no surprise then that I received a home brew kit for Christmas this year. Kyle & I brewed our first batch today. He likes to call it Frozen Water Brewing.

Here are a few prep notes:

Brew notes:
  • We used an old aluminum pot for brewing - seemed to work well.
  • Warm the extract early so it pours easily
  • When first boil happens, be ready for the over-boil. It happens fast. Pull the pot off the heat quickly
  • Sanitize, sanitizes, sanitize
  • The bottle filler tube from the True Brew kit works well to pull a sample our through the airlock hole. Sanitize tube before dipping
  • First spec gravity test, 4 hours after starting fermentation read 1.045 - right on target
  • Fermentation should be done when Sg reaches 1.009 - 1.003

We celebrated by running back to Keystone for bottles then stopping by Prism brewing in North Wales to try their beer.

Now we wait.

Hiding WordPress Login page

Saturday 08 of December, 2012
Our security guy showed me how to harvest editor names Wordpress. This combined with the known location of the login page makes the site susceptible to script kiddies plying their wares. A simple way to combat this is to create a redirect page somewhere and then restricting access to wp-login.php to visits coming from that page. I borrowed this idea from here. To implement this, I created my redirect page and added the following to the .htaccess file for the site.
# protect wp-login.php
Files wp-login.php (wrap in angle brackets)
   Order deny,allow 
   RewriteEngine on 
   RewriteCond %{HTTP_REFERER} !^http://www.mywebplace.com/wp-content/uploads/anoddname.html$ [NC] 
   RewriteRule .* - [F] 

/Files (wrap in angle brackets)

These lines are interpreted like this:
  •  for all files called wp-login.php
    • default to deny
    • If the HTTP_Referrer is not anoddname.html
    • don't rewrite the page, but return Forbidden HTTP code
I then created 'anoddfilename.html' and added a meta-redirect like this:
META HTTP-EQUIV="refresh" CONTENT="0;URL=http://www.mywebplace.com/wp-login.php"

These changes worked as expected. The site was fine, but to login you have to visit the site by hitting anoddname.html first.  There is one problem.  You cannot logout form the site.  That's because to logout you call wp-login.php again with ?action=logout appended to the url. Since you are on a page other then AnOddName.html at the time, you are forbidden from getting to the wp-login.php

To fix this, I added two more lines to the .htaccess file

.htaccess more
RewriteCond %{QUERY_STRING} ^action=logout [NC]
RewriteRule .* - [L]

With these lines added, .htaccess now checks first to see if you are calling with "?action=logout" Query_String. If so, it does not rewrite and stops. The complete .htaccess section is now:
Complete .htaccess
# protect wp-login.php
Files wp-login.php (wrap in angle brackets)
    Order deny,allow
    RewriteEngine  on
    RewriteCond %{QUERY_STRING} ^action=logout [NC]
    RewriteRule .* - [L]w
    RewriteCond %{HTTP_REFERER} !^http://www.mywebplace.com/wp-content/uploads/tbirdsarego.html$ [NC]
    RewriteRule .* - [F]

/Files (wrap in angle brackets)

Processing Object Properties in the PowerShell Pipeline

Sunday 21 of October, 2012
I was running a quick AD query via Powershell today and needed to export the results to a csv. The results contained two fields (lastLogonTimestamp and pwdLastSet) that are not human readable, but I needed them to be. There is a quick transform you can make on these field to convert them to a datetime value. It is simply:
Convert system time to datetime

That part is easy, but how do we do that in the pipeline so all the objects get converted before the export? To do so, we can create a calculated field using a specially crafted hash-table to describe the members to Select-Object. So this:

Select 'before'
select name, description, distinguishedname,pwdlastset,lastLogonTimestamp

Select after
select name, description, distinguishedname,@{LABEL='pwdlastset';EXPRESSION={[datetime]::FromFileTimeUTC($_.pwdlastset)}},@{LABEL='lastLogonTimestamp';EXPRESSION={[datetime]::FromFileTimeUTC($_.lastLogonTimestamp)}}

Looking a bit more in-depth, the pwdLastSet was modified to specify the column LABEL and the EXPRESSION in an array, with the EXPRESSION now set to the new, calculated value.

in case you are wondering, my full, one-liner, is a report on all disabled accounts in our directory

Get-Disabled Accounts
Get-ADUser -LDAPFilter {(useraccountcontrol:1.2.840.113556.1.4.803:=2)} -properties pwdlastset,lastLogonTimestamp,description| select name, description, distinguishedname,@{LABEL='pwdlastset';EXPRESSION={[datetime]::FromFileTimeUTC($_.pwdlastset)}},@{LABEL='lastLogonTimestamp';EXPRESSION={[datetime]::FromFileTimeUTC($_.lastLogonTimestamp)}}|export-csv d:\data\disabled_accts.csv -notypeinformation

Using Windows Server Web Platform Installer

Saturday 20 of October, 2012
Quick instructions for installing using the Windows Web Platform Installer tool in Windows server 2008 & Win 7. Note - if you are installing from Microsoft's Web Gallery, the process is much more automatic. The following procedure is necessary only if you need to install from the stand-alone package.

  • Open Server Manager and navigate down Roles/Web Server to the Default Web Site. Select the Default Web Site.
  • Using the Features View, in the Action Pane (Right), select Import Application(option missing? - see below)*
  • Browser to the zip file, select it and click Open, then Next.
  • The Application package will open with all steps selected. Click Next.
  • Select your database options (MySQL, and Create New are defaults) - Click Next.
  • Enter a new application path and database server info if you don't like the defaults. Scroll down to enter the sa password and the tiki db user password.
  • Click Next to run the install
  • After the install completes, open up a browser and point it at the site. (Default URL is http://localhost/tiki).
  • At this point the Tiki install will begin

(*Note: if this option is missing, download and install the Web Platform Installer v4 from here http://www.microsoft.com/web/downloads/platform.aspx. You will also need to install MySQl from the database category of Web PI as well as php from the Frameworks category)