From eBower Wiki
Jump to: navigation, search
(The Webserver)
Line 114: Line 114:
[ stoker.Json_Handler] on GitHub.
== Security ==
== Security ==

Revision as of 20:16, 29 March 2015

This is an evolution of my original stoker_mon project. And my evolution, I mean complete rewrite from scratch. This is a web server designed to control and monitor a Stoker power draft controller.

The Setup

The Stoker is a cute bit of kit, it's a PID controller for a BBQ pit. To control a fire you can control one of three components: heat, fuel, or oxygen. Since we can't bring the heat below combustion temperatures and it's hard (outside of a pellet stove) to control the fuel, the Stoker works on controlling the oxygen. If you can seal your grill such that it's oxygen-restricted and the fire will smother itself, you can use a Stoker. It uses a temperature probe as part of a feedback mechanism, if the temperature drops too low it turns on a blower that adds oxygen to the fire. Once the temperature is correct it shuts off the blower and closes an internal damper, cutting off the airflow.

It works great as a standalone item, you just set a few things from the front panel and let it do its thing. But it also has an Ethernet port (and possibly a WiFi interface) so you can control it remotely. However, the internal UI is really about the current temperature and some basic settings. And the security is pretty poor so exposing it through your firewall is a little scary. You know those stories about the Internet of Things where they're worrying someone will hack into a light switch and start a fire? Well with the Stoker there's *already* a fire!

I've done two things to help this. First, my Stoker is not connected to my LAN. It's connected to a Raspberry Pi which is connected via WiFi. This serves two purposes:

  1. The WiFi on my Stoker isn't reliable. It will drop connection periodically and I'll need to reboot to restore it.
  2. More importantly, the Raspberry Pi has much better firewall controls. As of now I have it configured to only allow access from my webserver. Over IPv6. I'm also tempted to configure it to be TLS encrypted and use client-side certs, but then the behavior is different for my Stoker compared to a vanilla Stoker and suddenly stoker_mon may work fine for me but be broken for you.

The crux of the stoker_mon project, however, is to periodically capture the data from the Stoker to expose it on the web UI. I use a standard Apache server running a slew of other applications (including this Wiki) and it's written in a mix of php5 and JavaScript. I've leveraged Highcharts for the graphing, thoughtfully freely available for non-profit projects like these.

The Stoker

I have a Stoker WiFi, but I've found that the WiFi isn't all that stable. It will periodically drop, and the Stoker itself has a pretty horrid security model considering its intended purpose is to control an active fire right next to your house. The new Stoker II may fix some of these issues, but so does a Raspberry Pi.

What you'll need is a Raspberry Pi with a physical Ethernet port and a WiFi dongle. The WiFi is how it connects to the Internet, the physical Ethernet port is how it connects to the Stoker. The first thing you'll want to do is the standard Raspberry Pi stuff. Use something like nmap -sP to find your current hosts, power up the Pi with the Ethernet port plugged in and run the command again to find the Pi. You should now be able to telnet in with pi/raspberry and run the initial setup to expand the storage, change the password, and whatever else you want to do. Of course, always run sudo apt-get update && sudo apt-get dist-upgrade to get the latest software. You should also add ipv6 to the bottom of /etc/modules or you'll be stuck in 2010...


First job is to get the WiFi running. If you run ifconfig you should see a wlan0, if not you'll need to find drivers. Now edit /etc/network/interfaces to include your network name and password:

allow-hotplug wlan0
iface wlan0 inet dhcp
        wpa-ssid "MyWiFi"
        wpa-psk "my_password"


Now we'll need to install a DHCP server. This is optional, you can also just fix your Stoker's IP address via the Stoker UI, but I prefer everything to be DHCP so I can move it between networks easily. Run sudo apt-get install isc-dhcp-server, edit /etc/dhcp/dhcpd.conf to include the following lines:

subnet netmask {

host stoker {
  hardware ethernet 00:60:35:xx:xx:xx;

This assumes that you're using and want to set up the Stoker at - make sure to replace the xx:xx:xx with your own Stoker's MAC address. You can find this in /var/lib/dhcp.leases as well.

Now we'll need to edit /etc/network/interfaces to include the following:

iface eth0 inet static


Finally, we'll want Apache up and running. We need to run sudo apt-get install apache2 php5 php5-curl to install it. Then we'll need to edit /etc/apache2/sites-available/default to include the AddType line in the /var/www/ directory setting:

        <Directory /var/www/>
                Options Indexes FollowSymLinks MultiViews
                AddType application/x-httpd-php .json
                AllowOverride All
                Order allow,deny
                allow from all


All I care about is getting the JSON API working, the user interface is useless to me but you can always write your own with this as a baseline. It's important to me that the API be transparent at this point, so I can't tell if I'm talking to my Pi or the Stoker directly. However I may add some enhanced features eventually that break this.

$curl_json = curl_init();
curl_setopt($curl_json, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($curl_json, CURLOPT_URL, '');
curl_setopt($curl_json, CURLOPT_RETURNTRANSFER, true);
$json_resp = curl_exec($curl_json);
$resp_info = curl_getinfo($curl_json);
if ( $resp_info['http_code'] == 200 ) {
  print $json_resp;
} else {


This is the critical component to protect, it passes through the JSON set API. I've commented in a working curl command to set my Pit Probe name and target temperature, simply substitute the ID with one of your own and the IP address with your Stoker's IP and it should work for you as well.

// curl -i -X POST -H "Content-Type: application/json" --data '{"stoker":{"sensors":[{"id":"370000127E6A0130","name":"Pit Probe","ta":180}]}}'
$curl_post = curl_init();
curl_setopt($curl_post, CURLOPT_POST, true);
curl_setopt($curl_post, CURLOPT_POSTFIELDS, $HTTP_RAW_POST_DATA);
curl_setopt($curl_post, CURLOPT_URL, '');
curl_setopt($curl_post, CURLOPT_RETURNTRANSFER, true);
$post_resp = curl_exec($curl_post);
$resp_info = curl_getinfo($curl_post);
print $post_resp;

stoker.Json_Handler on GitHub.


Finally, let's lock things down a bit. Run sudo apt-get install ufw. Now I run:

sudo ufw allow in on wlan0 from 2001:470:1f07:a86::/64

This allows access only from my IPv6 subnet on any port. I don't have ports open other than 80 (http) and 22 (ssh) and I intend to manually do host-based checks when writing to the Stoker so only my webserver can access the write interface.

The Webserver

I'm assuming you're familiar with getting a webserver up and running. You'll need to install the following:

sudo apt-get install apache2 php5 php5-curl curl git vim

This will install the Apache server, php, the php curl extensions, git (where the code will be hosted), and everybody should use vim! You can download the stoker_mon code by running:

git clone
  • Authentication is via Google Plus Authentication, much like my INSTEON/controller project.
  • There is a file that should be placed in /etc/stoker.ini that controls basic information like the Stoker IP address
  • You'll need to create /var/lib/stoker/ and place the daemon in there.
sudo mkdir /var/lib/stoker && sudo mv stoker_pull /var/lib/stoker/
  • You'll need to create /var/lib/stoker/cooks and change the ownership to www-data so the cook log files can go there.
sudo mkdir /var/lib/stoker/cooks && sudo chown www-data:www-data /var/lib/stoker/cooks
  • Optionally put the pi directory on your Raspberry Pi or just delete it.
  • Once you place the files in /var/www/stoker you should be all set.


Note that there's a font rendering issue with Chrome. Well, a font issue. If you get mis-rendered UTF-8 characters you can open up the Chrome settings, search for "Customize Fonts" and set the standard font to Tahoma (or anything else you want to play with).