Atwood RV furnace wont light

There are plenty of troubleshooting guides on the internet for rv furnaces, but what do you do after reading? You take it apart…

On a recent trip we turned on the furnace, blower ran, then within a couple minutes turned off. We had never had any trouble with it before. I did the usual thing one does, looked it up on the interwebs. The problem was I had no problem, other than it wouldn’t light.

What I have here is an “Atwood 8525-IV-DCLP L/D”, the L/D apparently means no outside access. “Less Door”? “Lost Door”? Dunno.

I had fan, I had gas solenoid clicks, I had ignition clicks, I had propane smell outside coming out the exhaust. I just didn’t have fire.

So to the local national super center for a space heater, and called it quits for trying to run the furnace for the trip. Nothing a few blankets and the space heater couldn’t handle. But it can’t stay broken.

There are two styles of rv furnace installs it appears. One where you have an access hatch where the furnace is installed from the outside, and one where there is no hatch and the furnace is installed from the inside with just an exhaust port going through the wall.

There is access to the guts of the furnace through one side of the furnace. Which is great if you can open the hatch from the outside and there it all is. In my case though I don’t have the outside access so all that stuff is conveniently pushed against the wall, under the kitchen counter. This is an outstanding place for a red LED and a sticker explaining its blinking fault patterns. Where you can’t see it.

So how does one get this thing apart?

There are 12v and thermostat wire connections, in my case I cut the 12v leaving room to splice back together, and the thermostat was wire nutted together.

So, ahem… needless to say, the gas needs to be off. The gas line is a 3/8″ flare connection, be sure to put a wrench on both sides to avoid bending anything. You won’t be able to just put a wrench on the fitting and lean on it, everything will twist up. So two 3/4″ wrenches are in order.

The exhaust port through the wall isn’t attached to the furnace to start. There is a stubby exhaust port recessed into the furnace, and a pipe that is attached to the vent leading outside, they just nest together and are not connected with any fastener.

There were 2 screws into the floor, opposite the outside wall, which were all that were holding the furnace in place fastener wise. Once these were removed I was able to pull the furnace away from the wall and off the exhaust vent. It was a snug fit. Also the exhaust for the heated air to heat the trailer was straight down, so there was some foam gasket material giving some resistance. This got it loose and out from under the sink and into the back of the truck.

Once home there were two things the furnace needed, power and fuel. I used a 12v jump pack I keep in the car to power the furnace, and a regulator/hose to a spare grill propane tank. The regulator you need to provide 11″ of water column pressure wise, and the hose needs to fit the regulator and have a 3/8″ female flare fitting on the other end. Got mine at Lowes as two separate pieces, about $30 out the door.

The last thing is the thermostat hookup. Thermostats are not complex things ultimately, they are a switch. So just wire nut the two ends together coming out of the furnace, that will tell it to be on all the time.

With the thermostat wires hooked together, once 12v is applied it will run.

I looked over this piece of shit in astonishment. These things many hundreds of dollars and they are complete junk. A single simple control board, a fan, heat exchanger which is just a winding exhaust tube, and a solenoid valve to turn the gas on/off with a burner/igniter. No sign of craftsmanship, no sign of any craps given. Hundreds of dollars…

So on the bench it did the same thing, all the clicks, all the fans, no fire.

It took a bit to figure out how to get it apart. What you have is 2/3 of the box is where the exhaust / heat exchanger lives, the fan pulls air in from the side and into the heat exchanger part of the box and in my case straight down into the floor. There are knockouts all over the box for different configurations. So the business end of it for everything is the part up against the outside wall. There you find the electronics and access to the burner/igniter/solenoid.

Here is the solenoid above the exhaust pipe, so input and output stacked up, with the fan on the left.

If you have the hardline for the gas input, which I think is the usual, you need to unscrew it from the solenoid because there it goes through a hole and captures the solenoid/burner assembly. So its just threaded in but just as with the gas connection you can’t just wrench on it, you need to support both sides. I was able to put a big crescent wrench on the solenoid assembly to hold it while putting a wrench on the hardline on the outside of the box. You have to be careful to not destroy things here, that solenoid assembly is a couple hundred bucks it appears…

Once that hardline is removed, with the furnace standing on end with the exhaust pointing up, you can unhook the electrical connections for the solenoid and igniter, take out 3 screws and lift out the whole gas assembly like you see here.

So now, hook it all back up but on top of the pile and test it. 12v to power it, and connect the thermostat wires together. Once you connect the 12v to whatever means you have, it will start to run.

If your foolish enough to try this, have a plan for how to deal with problems. Pulling the 12v will immediately turn off the gas. If you turn off the gas, it will stop burning. If the place catches fire, have a fire extinguisher. Or better yet, do not do as I did. Thats probably best.

What I found was that it would light, a tiny little bit, for a few seconds, and then it would go out. Do this 3 times 30 seconds apart or so, and then the red led on the control board would blink 3 times then pause, saying it had locked it out for failure to ignite.

The igniter was making good spark, it was lighting, just it appeared the flow of gas was no good.

Two screws hold the burner/igniter assembly on, that will expose the orifice which may need cleaning. Nope, clean as can be for me.

I then took the solenoid to a bench DC power supply, and cycled it. Seemed ok… then with the orifice out, I put compressed air gently into the valve. When the solenoid was open it was barely open. Here was the problem.

A few more cycles, I upped the amperage limit on the power supply to see if it was just not getting enough to open fully, and then one cycle it made a pop and it was wide open, not restricted at all… My solenoid had somehow stuck closed.

I know when it comes to other gas appliances like a furnace or water heater there is a common “tap the solenoid” fix for things like this. Sure enough this is what it needed.

I put it back together on top of the pile and this time… fire!

Here is a pic of the test setup. Remember, safety third as a great man once said.

Problem solved! Lets put it back together. And lets test it again before we go through all the trouble of re-installing it.

No joy. It would light but wouldn’t stay lit. It would kinda flutter out and then try again over and over. So its better but not ok now that its put back together.

Time to stand and stare at it.

One of the troubleshooting checks is if exhaust is blocked enough it won’t work. I have the exhaust port hanging off the side of the bench, can of paint counterbalancing it. No problem there.

There are two sides to the fan. One moves air from inside the trailer over the heat exchanger and out to the vents. The other side pushes air through the heat exchanger, clearing out any air/fuel mix that may explode from a failed ignition, and then providing air for combustion and pushing exhaust out when lit.

The source of air for the combustion is pulled from the same little compartment that the exhaust exits from. Normally exhaust is taken the rest of the way out through the side of the trailer so you don’t die. On the bench the exhaust doesn’t make it outside the box and… is drawn back in and is tried to be uses for combustion. This of course is counterproductive.

Ah ha! What we need is a tail pipe.

To the recycle bin, and off with the bottoms of some tomato cans, tape those together and bam. Furnace runs like a champ! I just used blue painters tape, it probably would catch fire if left to run for long. And the cans get hot. So don’t burn your garage down, and don’t burn your hand. Better yet use something not held together with tape.

Back to the RV and if it sticks again, give it a little tappy-tap-tap on the solenoid before major surgery.

test-kitchen config hijinks part 2

In part one we looked at how to share chef zero data across multiple cookbooks by creating a central repository and using environment variables to reference it.

In part two we look at how to share the config file in its entirety. This isn’t chef specific like part 1, there is chef cookbook content (setting a variable of cookbook name), but overall its easily ignored if not pertinent to you.

In part one we put essentially pointers back to the common location for all of our chef zero bits, but you have to put those pointers in every kitchen config for all the cookbooks.

Step 1, we need a default kitchen config.

In my case most kitchen configs were nearly identical, they came out of chef code generation (as ruby templates) and the cookbook name was poked into a couple places and some default values set for security groups and IAM roles. So taking the most vanilla one I had I copied that into the root of the kitchen_shared repo as ‘.kitchen.yml.erb’ and worked from there. If your starting from scratch, just copy the stock config.

Now that we have a common kitchen config, its time to reference it from all the cookbooks. Templates can essentially include other templates. There are a couple ways to include template info, this is a way I found that works.

<% @cb_name = File.readlines("./metadata.rb").select { |line| line =~ /^name/ }[0].split(" ")[1].gsub("'", "") %>
<%= ERB.new(File.read("#{ENV['kitchen_shared']}/kitchen_yml.erb"), nil, nil, eoutvar='_kitchen_yml').result(binding) %>

This now becomes your default kitchen config for all current and future cookbooks. It does some ruby to dynamically figure out the cookbook name from your cookbooks `metadata.rb` file, sets that as a variable which is available to the new instance of a template generated by the `ERB.new(…)` call, from you guessed it, our common kitchen config.

Step 2, now move on to the common ‘.kitchen.yml.erb’.

Below are excerpts of config files, none of which are complete valid configs, they are just to help explain the concepts.

In your ‘.kitchen.yml.erb’ you may have the environment variable references from part 1 or it may be just a bone stock kitchen config which is fine. Here are some examples of what you can put inside the common config

Simple template syntax time, putting ruby inside <%= %> makes it display the result of said ruby code in the resulting templated output. Putting ruby inside <% %> means no output from that block. That pretty much sums it up for what we do here but there is no lack of docs about ruby templating out there if you want to know more.

If your using kitchen-ec2 to spin up your instances, its handy to tag the instances with some metadata:

driver:
  tags: { Name: "test_kitchen-<%= ENV['USER'] %>-<%= @cb_name %>" }

When you look in aws at your instances, you will end up with your kitchen instances being self descriptive with a Name tag like:

test_kitchen-bob-redis

This is a test-kitchen instance started by userid bob (on the host that created it) which is for a cookbook called ‘redis’.

Again in kitchen-ec2/aws, if you needed your instance to use a different ssh key depending if you were in your CI environment or on your laptop:

driver:
  <% if ENV['USER'] == 'jenkins' %>
  aws_ssh_key_id: jenkins-test-kitchen
  <% else %>
  aws_ssh_key_id: test-kitchen
  <% end %>

For a non-kitchen-ec2 example, lets change runlist depending on cb_name:

driver:
  suites:
  - name: <%= @cb_name %>-kitchen-1
    run_list:
      <% if @cb_name == 'elasticsearch' %>
      - recipe[elasticsearch::default_2x]
      <% elsif @cb_name == 'redis' %>
      - recipe[base_cb::default]
      - recipe[redis::test]
      <% else %>
      - recipe[<%= @cb_name %>::default]
      <% end %>

You can see we set the name of the instance to have the cookbook name in it via the cb_name variable, and depending on cookbook name we set runlists, with a fall-thru default.

Again this is chef stuff, but the message of this post is about the templating and sharing not chef specifically.

Finally how do we test our new-fangled scheme? Super easy. From the root of the cookbook where you would run your kitchen commands just feed our new 2 line kitchen config file to the ‘erb’ binary. Lets look at our last example of the suite section of the config from a cookbook named redis:

$ erb ./.kitchen.yml

suites:
  - name: redis-kitchen-1
    run_list:

      - recipe[redis::test]

Now if you look at that gap between ‘run_list:’ and ‘- recipe’ you see where the template engine pulled out the conditional stuff masked by the <% %>. There are ways to strip those lines out, but it wasn’t playing along and in the end we never see the result so I didn’t spend time on it, and kitchen doesn’t care.

So just iterate from here, whenever you need to deviate from the defaults, throw in a conditional in your shared config and check your work.

But also this lets you do things like change the chef omnibus version for every test-kitchen run from one place, no conditional, just shared code.

provisioner:
  require_chef_omnibus: 12.13.1

Never do the “now we go through all the cookbooks and change the ” dance again… after you set this up 🙂

test-kitchen config hijinks part 1

In part 1 we will look at DRYing up chef zero configs for test-kitchen and chef cookbooks.

A few things become apparent while making test-kitchen work in all your chef cookbooks, there is a chuck of this which is repeated and would be best to do once and reference everywhere.

Most notably the chef zero environments, data bags, nodes, etc stubs you need to service cookbooks that search and use data bags and all do all the things. This is what we will look at here.

The ‘.kitchen.yml’ config file is not only yaml, its also parsed by a Ruby template engine. This lets us do interesting things.

First, we need a common place to refer to from all the test-kitchen configs, lets for example make a new Git repo for this task called ‘kitchen_shared’.

Inside kitchen_shared repo make a simple directroy structure.

kitchen_shared/
├── data_bags
│   └── users
├── environments
└── nodes

Now place inside those directories files representing the appropriate subject. Here are some examples:

# cat kitchen_shared/data_bags/users/bob.json
{
  "id"       : "bob",
  "comment"  : "Bob Smith",
  "action"   : "create",
  "ssh_keys" : [
    "ssh-rsa thiskeyiswaaaayshortAAAAB3NzaC1yc2EAAARCV/g9OK1Oc0X04DPV0MiECguZmH/FqS13 bob@foo.local"
  ],
  "password" : "wooooooosekret!"
}

$ cat kitchen_shared/environments/database.json
{
  "name": "database",
  "default_attributes": {
  },
  "json_class": "Chef::Environment",
  "description": "kitchen database env",
   "cookbook_versions": {
  },
  "chef_type": "environment"
}
$ cat kitchen_shared/nodes/database01.json
{
  "name": "database01",
  "chef_type": "node",
  "json_class": "Chef::Node",
  "chef_environment": "database",
  "run_list": [],
  "automatic": {
    "ipaddress": "1.1.1.1",
    "hostname": "database01"
  }
}

Thses match what you would get from knife if you did a show on a node or an environment etc. They aren’t special, they are legit configs that match whats in a real server, they are just loaded into chef zero instead.

Add the appropriate things for your needs, the above are just random examples.

The .kitchen.yml docs show how to reference locations for this info, but relative to the current path and for a typically local and unique to each cookbook set of data. Ex:

provisioner:
  name: chef_zero
  nodes_path: '../../nodes'
  data_bags_path: '../../data_bags'
  environments_path: '../../environments'

So now to share this we can start using the Ruby template-fu.

Add an environment variable which contains the path to where the kitchen_shared repo is checked out to your shell so its always set through whatever means appropriate, Ex:

$ echo "export kitchen_shared=~/repos/kitchen_shared" >> ~/.bash_profile
$ . .bash_profile

Now use that to reference the paths in the kitchen_shared repo from your .kitchen.yml like this:

provisioner:
  name: chef_zero
  nodes_path: '<%= ENV['kitchen_shared'] %>/nodes'
  data_bags_path: '<%= ENV['kitchen_shared'] %>/data_bags'
  environments_path: '<%= ENV['kitchen_shared'] %>/envs'

Update your cookbook creation procedure to include this as standard and your set.

Now you have one consistent and shared set of data to populate the test-kitchen chef zero servers. Make a change there, push the repo, and everyone working on chef as well as any CI/CD processes can track that repo and use and expand and be DRY.

More to come in part 2.

Ansible at home

What often is the hardest part of learning something new “just because” is what to do with it after you have accomplished Hello World.

Ever wanted to play with Ansible? Use it at home. Why? Because its dead simple to get started and who likes doing things twice or taking build notes to follow by hand if you can find them?

And if you do any one-board computers like Raspberry Pi, Odroid etc that live on a sd card, you will end up with it getting corrupted and rebuilding it. Using config management makes things much less sigh inducing when that happens and you don’t have to keep making a golden image after every update if thats your idea of saving your work.

Yes you can setup a Puppet or Chef server, or distribute the modules/cookbooks aound and run either one without a server. Or I can put some stuff in a github repo, pass out ssh keys, learn a bit about something new, and not feel like your at work when your home-gaming.

How I did it, an overview:

Git

I could make myself a git repo inside a bittorrent sync share to keep history and keep it safe, but since GitHub changed its pricing and account model and I have private repos far as the eye can see I just use that.

Skip this step or use another way to track your code, but track it somehow so we iterate not recreate.

Ansible Install

On Mac if you use Homebrew (why aren’t you?) its the usual dance:

$ brew install ansible

Use whatever package management makes sense for your OS of course.

SSH Keys

To get to all your hosts to manage Ansible uses ssh by default. Drop a pub ssh key onto the host for the root user, use a passphrase and ssh-agent.

Playbooks

There are only two files you need to get started, one to hold the info on the hosts you want to manage and one for the playbook, which is a YAML file with what needs to be done on the hosts.

Example hosts file:

[server1]
192.168.10.101

Example base playbook, everything has a “name” which you can use to self document and is displayed in the ansible run:

---
  - hosts: server1
  gather_facts: no
  remote_user: root
  tasks:
    - name: install screen
      apt: name=screen state=latest

    - name: root .bashrc
      copy: src=files/root.bashrc dest=/root/.bashrc owner=root mode=0644

    - name: create /opt/local/bin
      file: path=/opt/local/bin state=directory mode=755

This is all you need to get started, assuming all is lined up right with ssh, make it go:

$ ansible-playbook -i hosts base_playbook.yml

PLAY [server1] *****************************************************************

TASK [install screen] **********************************************************
ok: [192.168.10.101]

TASK [root .bashrc] ************************************************************
changed: [192.168.10.101]

TASK [create /opt/local/bin] ***************************************************
changed: [192.168.10.101]

PLAY RECAP *********************************************************************
192.168.10.101             : ok=3    changed=2    unreachable=0    failed=0

Above you see screen was already installed so “ok”, it updated the .bashrc with one at the local path specified in the playbook, and made the /opt/local/bin dir. Its that simple.

You can include a base playbook into a role playbook, and get all complicated to do all sorts of things, but this will get you going and on your way to learning something new and keeping that effort around you put into building that server for reuse.

Many projects you find on this site will include Ansible as part of the writeup. Below are some good starting points if you want to follow along.

Scheme?

You can find some best practices for directory layout for managing your Ansible stuff here, but there is no specific need for anything to be anywhere special that I’ve found. So to get started I simply made a new github repo and made the host file and the playbook yml files right in the root. I then got to the point where things were a tad messy and made a ‘files’ directory as you can see referenced above because it was similar to what i’m used to in Chef and it hid most of the misc stuff away.

The point being, do what your comfortable with and it can evolve or not. At home things don’t change often so keeping things very simple helps when you show up after not touching things for weeks or months.

What really got me going with this subject and then to Ansible was as mentioned above, building something on a one-board computer using sd card to boot and dealing with the fragility of the FS getting corrupted from power interruptions. Whether its the one in my truck or the one I set out when we are on a trip with security camera stuff on it, I didn’t want to have to re-build the thing and remember all the steps I took to get it setup. Taking notes? Why not just put it in config management and be able to re-create and evolve? So thats what I did. I’ve got notes that actually implement the system it describes, all I have to do is have ssh access and I can clone the repo and make changes, and I can worry less (and share!).

So there is no big story to tell about how to configure and manage Ansible as a service from here as there is with Chef/Puppet/CFEngine etc. Just focus on the task at hand and become familiar with new tech!

Refs

Ansible getting started
Ansible intro to playbooks