Daniel's Weblog
Posts About
Tags Colophon

Tags / Posts

PyCharm Quick Documentation Sphinx Support

A list of the Restructured Text Syntax and Sphinx roles that PyCharm supports in docstrings.

Be sure to set “Docstring format” to “reStructuredText” in setttings.

Function Parameters:

def do_the_thing(the_thing, another_thing=None):
    """
    :param int the_thing: The thing's primary key
    :param another_thing: A second thing to also do specified by an int or a string
    :type another_thing: Union(int, string)

    :returns: A string with the outpu text form running the thing
    :rtype: str
    """

PyCharm will reorder the params in the documentation based on the order of the params in the function definition.

:param TYPE PARAM_NAME: DESCRIPTION

is a syntactic sugar for

:param PARAM_NAME: DESCRIPTION
:type PARAM_NAME: TYPE

and is functionally equivalent. The only exception is that in the shortcut the type can only be a single word. There is no syntactic sugar for specifying the return type and description on the same line.

Notes:

  1. Multiple Supported Types

    :type PARAM_NAME: TYPE_ONE or TYPE_TWO
    :rtype: TYPE_ONE or TYPE_TWO
    

    Can be used to list multiple types for a single parameter or return value. PyCharm will render this as Union(TYPE_ONE, TYPE_TWO)

  2. List types

    List types can be specified by list[str].

Default Role

The default restructured text role `surrounded by backticks` has no meaning in restructured text and can be used for anything. It can be a nice way to indicate that you are referring to a python variable, method, or parameter. PyCharm will italicize any text surrounded by backticks.

Transitions

PyCharm will render a horizontal line based on any four or more repeated punctuation characters

Lists:

Bullet list

- This is a bullet list entry
- This is another bullet list entry
* Stars also work for bullet lists

Enumerated List

Enumerated lists do not work. The following:

1. This is an enumerated list item
2. This is another
#. This item should be auto enumerated with the number '3'

renders as follows:

. This is an enumerated list item
. This is another
. This item should be auto enumerated with the number '3'

Something is happening because item is placed on a new line, but it does not render as a numbered list

Definition List

doe
    A deer, a female deer
ray
    A drop of golden sun
me
    A name I call myself

will render properly.

Option List

Useful for listing command line arguments. Must be at least two spaces between the definition and the description.

-a           this flag sets the variable a
-b filename  sets the variable b to the provided filename
--input=other  this will also render correctly
/V           even DOS/VMS-style options will work
-c           long descriptions can be
             broken over multiple lines

Linking:

Sphinx defines several roles for the Python domain:

  1. :py:mod: for modules
  2. :py:func: for functions
  3. :py:data: for a module-level variable

The full list is available in the Sphinx docs

PyCharm supports a small selection with a slightly different syntax as listed below.

Linking to a class

:class:`SomeClassName`

This does not work inside of :param:, :type:, :return: descriptions.

Linking to an Exception

:exc:`SomeExceptionName`

This does not work inside of :param:, :type:, :return: descriptions.

Linking to a URL

http://someurl.com
`Link Name <http://someurl.com>`_

This does not work inside of :param:, :type:, :return: descriptions.

Math

Inline Math Formatting

PyCharm will italicize the following and make the powers into superscripts.

:math:`a^2 + b^2 = c^2

Other Semantic Markup

Sphinx has a selection of other miscellaneous roles documented here. The ones PyCharm supports in docstrings are listed below.

Linking to a PEP

:pep:`8`

Linking to an RFC

:rfc:`1462`

Other supported Restructured Text features

  1. Headers
  2. Sections
  3. Literal blocks
  4. Images

Restructured Text features that aren’t supported:

As of Dec 2019

  1. Line blocks
  2. Block quotes
  3. Doctest blocks
  4. Tables
    • They kind of work because of the headers, but they’re not great.
  5. Field lists
  6. Footnotes
    • PyCharm tries to make them into external links which fails.
  7. Sidebars
  8. Line Block

Notes on using Python Flask in 2019

Flask is a microframework for Python based on Werkzeug, Jinja 2 and good intentions.

Learning

Miguel Grinberg’s Flask Mega-Tutorial is the undisputable place to start and reference. I also strongly recommend his book, Flask Web Development. Be sure to get version 2.

Project Template

I maintain a reasonably well-documented skeleton of a Flask app built with the application factory and multiple configs.

Visual Studio Code

I don’t need to extole the virtues of VS Code.

Useful plugins:

Debugging:

Initial configuration:

  1. Enable the python interpreter by opening any Python file *.py. In the bottom left corner of the screen you should see which interpreter you’re using
  2. Switch to the debug module
  3. Select “Add Configuration” from the configuration dropdown
  4. Select “Flask” from the menu that appears
  5. Set the application path. If you’re using my project template the enterance file is myapp.py
  6. VSCode will now show you the file launch.json that it generated. If you want to set or change any environment variables you can do so here.

To run your code switch to the debug module and press the green arrow!

Bootstrap

Use Bootstrap-Flask, not Flask Bootstrap which hasn’t been updated since May, 2017 and doesn’t support Bootstrap 4.

The render_field() and render_form() macros are particurarly useful.

OpenID Connect (oidc)

I have had the most luck with Flask PYOIDC

Background tasks

RQ with Redis

Supervisord is an easy way to run the RQ workers. It’s written in Python2, but can run Python3 applications / scripts without any issues.

Deploying to Azure

Deploying a Flask app to Azure is remarkably easy–props to the team responsible for the wizardry that happens under the hood.

  1. Log in to <portal.azure.com>

  2. Select “Create a Resource” from the top left.

  3. Search for, select, and create a “Web App”.

  4. Fill in the web app details

    • Choose your subscription and resource group.
    • Give your application a name
    • Choose “Code” as your publish method
    • Choose the proper version of python for your runtime stack
    • Linux as your operating system
    • Choose the location most applicapable to you
  5. When the deployment is done open your new resource. The deployment process usually takes 20-30 seconds.

  6. Select the “Deployment Center” blade and the “Local Git” option.

  7. Select “App Service build service” and complete the process.

  8. The contents of the Deployment Center section has now changed. Azure has set up and empty git repository that we can push code to which it will build, host, and run. Copy the “Git Clone Uri” and add it to your local repository with the command

    git add remote [remote name] [remote uri]
    

    I like to call my deployment hosts “deploy” so for example:

    git add remote deploy https://daniel-flask.scm.azurewebsites.net:443/daniel-flask.git
    
  9. To actually deploy your code to this repository run:

    git push deploy master
    

    You will be prompted for a username and password which can be found by clicking on the key icon labled “Deployment Credentials” at the top of the Deployment Center.

  10. Almost done! If the startup file isn’t named “application.py” and/or isn’t located in the repository’s root folder Azure won’t find it. Open the “Configuration” blade and then to the “General Settings” tab. Fill in the “Startup Command” field as follows:

    gunicorn --bind=0.0.0.0 --timeout 600 [startup file minus extension]:[app object in that file]
    

    For example, using my my project template

    gunicorn --bind=0.0.0.0 --timeout 600 myapp:app
    

    You can find the full reference here

  11. To set environment variables navigate to the “Configuration” blade and add the “Application Settings” tab. You can reference them in your application with os.environ.get('Environment Variable Name')

  12. To restart your application to make the changes take effect navigate to the “Overview” blade and press the “Restart” button. Or push new code!

And that’s it! You can find the URL of you application on the “Overview” tab.


A small recipe for combining WTForms and the Quill text editor: I’m using Flask-WTF so this isn’t exactly the same as a pure WTForms implementation, but it should get anyone else on the right track.

The Quill text editor defines its contents as a delta object.

“Don’t be confused by its name Delta—Deltas represents both documents and changes to documents.”

When a user submits the “save changes” button we can use the Quill API to access the contents of the text editor, serialize it with JSON.stringify(), put that string in a WTForm field, which then gets submitted to the backend. In order to keep the form nice and clean we can hide that field from the user.

forms.py

  • The first hidden field is called “delta”, which holds the serialized contents of the delta object.
  • The second hidden field is called “length” which holds the length of the actual content in the delta object.
from flask_wtf import FlaskForm
from wtforms import SubmitField, HiddenField, IntegerField
from wtforms.validators import Length, NumberRange
from wtforms.widgets import HiddenInput

class CreatePost(FlaskForm):
    delta = HiddenField(
        'delta',
        validators=[Length(0, 255)],
    )
    
    content_length = IntegerField(
        label='',
        validators=[
            NumberRange(2, 255, "Blank posts aren't very interesting.")
        ],
        widget=HiddenInput()
     )
     
    submit = SubmitField('Create Post')

template.html

This flask template takes an argument named “form” containing a CreatePost object (defind in the example code above).

{% block page_content %}
<div class="row justify-content-center">
  <div class="my-sm-2">
    <div class="page-header">
      <h1>Read a Post</h1>
    </div>
    <!-- Create the editor container -->
    <div id="editor">
      <p>Hello World!</p>
      <p>Some initial <strong>bold</strong> text</p>
      <p><br></p>
    </div>

    <!-- 
    Form submission is handled by FlaskWTF. It has a hidden field, which
    is updated with the contents of quill.getContents() when the submit
    button is pressed
    -->
    {{ render_form(form) }}

    <!-- Include the Quill library -->
    <script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>

    <script>
	   // Initialize the Quill editor
      var quill = new Quill('#editor', {
        theme: 'snow'
      });

      // When the submit button is pressed, retrieve several pieces of info
      // from the QuillJS API (https://quilljs.com/docs/api/#content), copy
      // them into to WTForms hidden fields, and submit the form
      var submit_entry = function () {
      
        // Get the contents of the text editor
        var hidden_text_field = document.getElementById('delta');
        hidden_text_field.value = JSON.stringify(quill.getContents());
        
        // Get the length of the contents of the text editor
        var hidden_length_field = document.getElementById('length');
        hidden_length_field.value = quill.getLength();
      }

      // Attach the onclick function to the submit button Flask-WTF creates
      var new_post_form = document.getElementsByClassName('form')[0];
      new_post_form.onsubmit = submit_entry;

    </script>
  </div>
</div>
{% endblock %}

Temperature Sensors Part 5: Assembling PCBs & Future Plans

I finally received my printed circuit boards in the mail, time to assemble them.

This is post number 5 in a series describing my DIY temperature and humidity sensors.

Printed Circuit Boards

OSH Park’s packaging is not subtle.

The boards are indeed a dark purple, which my camera didn’t properly capture. Here’s what they look like unpopulated and populated:

On the top right there’s a little bit of what I can only assume is someone else’s screen printing that overlapped on to my board. No harm done, and it adds character. The little points that held the panel together during production are rather sharp, I ended up cutting off the points so I wouldn’t stab myself.

It’s not perfect, though. The empty space between components is smaller than it seemed on the computer screen and I didn’t leave enough space between the components. I had to tilt headers connecting to the temperature sensor so it would fit along side the ESP8266.

Despite that, it’s definitely an improvement over the hand-made version.

Future Plans

So where to go from here? I’ve been using this for temperature sensors, but in reality I’ve created a 3.3V based I²C base for the ESP8266. I could replace the temperature sensor with…

  • Another atmospheric monitoring sensor with barometric pressure as well
  • An infrared array to determine if a human (or dog, maybe?) is present
  • A 16x2 LCD Display that could easily update over Wi-Fi
  • A Sparkfun Qwicc Adapter so I can daisy-chain many I²C sensors together (An external power supply may be required, depending on how crazy you want to get)

But it doesn’t have to be limitted to I²C interfaces!

  • I’ve been thinking about using a non-invasive current sensor so I don’t have to walk all the way to the basement to check on the washer and dryer
  • A particulate matter sensor so I can detect air polution hazards (like if my housemate is cooking extremely spicy chicken)
  • Or even something as simple as a reed switch to tell if a door is open

Pens, Pencils, and Paper Products in NYC

Need more pens, paper, and other writing products? Me neither, but I’m going to buy some anyways.

MUJI Fifth Avenue

My preferred Muji location is right across the street from Bryant Park and the New York Public Library (Which is also worth visiting either for books or to reenact Ghostbusters). They also have other locations throughout the city including Hudson Yards.

Google Maps describes Muji as “Minimalist Japanese retailer with a wide range of generic products, including apparel & home goods.” which is not technically wrong, but disregards their offerings of pens, mechanical pencils, and unbleached paper products (envelopes, pads of paper, sticky notes, etc.). None of their products are branded.

At their door is a table full of ink stamps where you can personalize your new notebook or an envelope you’re about to send to someone.

Of particular note are their following items:

  • Capped Gel Ink pens

    Wide range of covers, comfortable to hold and come in multiple sizes. Good for every day writing and note taking. Like most gel pens they will smudge on glossy surfaces, and not very water resistant. The pens can be bought individually or as a set.

  • Envelopes

    Okay, they’re really just envelopes. But they’re made out of kraft paper which makes them stand out and feel special.

  • Aluminum Round Fountain Pen

    This is probably the most expensive pen in the store, but it’s pretty inexpensive as fountain pens go. If you’re looking to dip your toes in the world of fountain pens this is a good way to start. Muji only sells black ink cartridges for this pen, but elsewhere you can buy convertors (like at Goods for the Study Mullberry detailed later) that allow you to refill it with whatever ink you like.

Stationary products are on the ground level, household goods, clothing, and more can be found in the basement. Muji products can also be ordered online on their website.

Casey Rubber Stamps

On East 11th Street between First and Second Avenues is a tiny store almost overflowing with rubber stamps. They’re more expensive than the stamps you’d find at your local craft store the broad selection is incredible. See something in the catalog that isn’t on the shelf? Wait 10 minutes and they’ll assemble it for you. Need custom stamps? They can do that too.

As the brochure says, “All of our equipment is state of the art circa 1955”. You can also order online from their website.

Kinokuniya New York

While Muji is restrained and spacious, Kinokuniya Books is doing their best to use every single square foot. On ground floor is a great collection of art, architecture, and design books. Upstairs is a Japanese cafe, manga, anime, and some western comic books too. In the basement is a huge collection of Japanese literature. I can’t read Japanese, but the way the series are color coordinated on the shelves is incredibly satisfying.

But we’re here to talk about pens, and a quarter of the basement is dedicated to pens, pencils, and decorative cards. Unlike Muji they don’t produce their own products, but if you need to restock your supply of Marvey LePen or pick up some more Blackwing pencils this store is conveniently located.

Goods for the Study Mullberry

Leaving midtown and heading south takes us to Goods for the Study Mulberry which is under the same ownership as McNally Jackson Books just around the corner. This store is split between two adjacent storefronts. On the right is notebooks, paperclips in the shape of animals, pen cases, paperweights, rulers, and more.

The store on the left is a more interactive experience. Jars of pens and mechanical pencils fill the walls and you’re invited to try them out. It’s a bit reminiscent of the Ollivander’s Wand Store in Harry Potter. If you’re searching for the perfect writing utensil this is the place to go.

Fountain pens and jars of ink are available here too. This in fact is where I bought a converter for my Muji fountain pen.

CW Pencil Enterprise

CW Pencil Enterprise takes a different approach from Goods for the Study. Instead of having many options, they have a small, carefully curated selection of pencils. If your idea of a writing utensil is a piece of wood with graphite in the middle, this is the place to visit.

Bowne Printers

Part of the Seaport museum, this is another store in two parts, Bowne and Co. Stationers has my favorite NYC-themed postcard designs. Right next door is Bowne Printers which is a 19th print shop selling cards and prints made there. They can also be commissioned for business cards and other prints.

Places I have not yet visited


Temperature Sensors Part 4: PCBs and Programming

This is post number 4 in a series describing my DIY temperature and humidity sensors.

Printed Circuit Boards

For the past month my two prototype sensors have been dutifully reporting the temperature and humidity in my house with any complaint. At this point I want to get a PCB made to make assembly easier. I’ve never done any serious board layout, but learn.sparkfun.com has an well-written, two-part tutorial called Using EAGLE.

This is what I came up with after an evening of work:

I decided to order the boards from OSH Park who are charging me a grand total of $7.35 for three boards (with free shipping!).

These differ from my hand-made prototypes in two ways:

  1. I’ve added a three holes on the board (labeled J3) for easy access to VCC, 3.3V, and GND
  2. There’s a button! More on that in the next section

Programming Changes

Up to this point all of the sensor’s settings have been hard-coded in the program. If I wanted to change a sensor’s name, it’s recording interval, or the InfluxDB server it reported to I had to change the program and re-flash the ESP8266 with the new version.

This process entails the following:

  1. Remove ESP8266 from sensor and place on breadboard
  2. Attach FTDI breakout to the breadboard
  3. Connect FTDI and ESP8266 together going through a level shifter
  4. Make changes to program
  5. Flash the new program to ESP8266
  6. Put ESP8266 back in sensor

I made a jig to make this process easier, but it’s a pain, and if you need an FTDI breakout to program this sensor it drives the cost up even more at $15.95 for the FTDI breakout (you could also use an Arduino UNO with the ATMEGA removed, but that’s even more of a pain) and $2.95 for a logic level converter .

This is where the button comes in. If you hold the button down while plugging the sensor in it will enter configuration mode. In this mode the sensor acts as a Wi-Fi hotspot and broadcasts a network called “Sensor Setup”. Navigating to 192.168.4.1 provides configuration options.

These settings are saved in the ESP8266’s flash memory so they persist across power cycles. To leave the configuration mode, simply unplug the sensor and plug it back in again.

“But wait!” you cry, “doesn’t the ESP8266 only have two GPIO pins in this configuration? And you’re using them both for I2C to communicate with the sensor!” And in fact you’re right, only two pins are dedicated to GPIO in this configuration… but the RX and TX pins can be repurposed as GPIO pins. Check out how on Stack Overflow.

The full code can be found on Github


Do you like planes? Do you ever wish you could… track them? This guide will cover setting up your Raspberry Pi as an ADSB feeder and sending the data to various aggregators.

I’m going to be using a Raspberry Pi model 1B+, but the instructions should work for other Raspberry Pi boards and possibily other Debian systems as well.

What you need

  • A single-board computer with a good power supply. I’m using a Raspberry Pi 1B+
  • A monitor for said-computer and a keyboard
    • Alternatively you can turn on SSH by default and then do everything remotely, but I’m not going to cover that here
  • A RTL-SDR dongle and antenna. RTL-SDR.com has good kits.
  • An internet connection for said single-board computer
  • A clear view of the sky through a window

Part #1: Set up Raspbian

  1. Let’s start with a clean install of Raspbian Lite. Follow the instructions in the official guide.

    • As of this writing, the most recent version is Raspbian Stretch.
  2. Boot it up for the first time and login!

    • In case you forgot, the default username is “pi” and the password is “raspberry”
  3. Drop in to the configuration utility with sudo raspi-config and lets go through some defaults to make life better(tm)

    • Change the user password. THIS IS NON-NEGOTIABLE. You are not allowed to read the rest of this guide unless you change the password.
    • Change the hostname in Network Options > Hostname
    • Set up Wi-Fi *(if applicapable) in Network Options > Wi-Fi
    • Turn on SSH in Interfacing Options > SSH
    • Change your locale in Localisation Options > Change Locale
      • As an American, I select en_US.UTF-8 here and then select it again when asked what should be the default. I don’t find myself using the Euro or Pound symbol on my ADSB feeders :-)
    • Set your keyboard to the appropriate layout in Localization Options > Change Keyboard Layout
      • I use “Generic 105-key (Intel) PC” and “English US”. To change from “English UK” you have to select “other” and then it will give you a greater list of options.
      • Unless you know you have an AltGr key, just say “The default for the keyboard layout”
      • And again, unless you know better just choose “No compose key”
    • When you’re done select Finish and let it reboot when prompted.
  4. Now that we’re back from the reboot, test your network connection! ping 8.8.8.8 It’s OK, Google’s DNS servers can take it.

  5. Time to update and upgrade. While you’re waiting you can read about the difference here

    • sudo apt-get update
    • sudo apt-get upgrade
    • If you don’t want to deal with those pesky prompts, you can add the flag -y (which stands for “YES”) to each command like sudo apt-get update -y
  6. Install git with sudo apt-get install git

    • I am going to take this time to also install a few other programs I like, including vim, screen, and sl which displays a steam locomotive everytime you misspell the command ls.

Part #2: Set up ADSB!

Part 2-A: FlightAware

The company Flightaware provides free enterprise accounts for anyone who feeds ADSB data to them and also maintains the most recent version of the dump1090 software, so we’ll start with them.

There are two pieces of software you need to know about:

Dump1090 is the software that actually interacts with the RTL-SDR dongle and interprets the ADSB data. The “1090” part of it’s name refers to the frequency 1090 MHz which ADSB runs on. More details about that can be found on the Cincinnati Avionics webpage.

PiAware is FlightAware’s custom software that sends them the data Dump1090 produces, does multilateration (more on that in Step #6 below), and a few other nifty features.

Instructions:

  1. Register for a FlightAware account
  2. Plug in your RTL-SDR dongle if it wasn’t already (again, if your Pi reboots when you do that you probably need a better power supply!)
  3. Follow their instructions
  4. Claim your receiver at flightaware.com/adsb/piaware/claim
    • This works by comparing your web browser’s IP address with the IP address of the new transmitter. Make sure you’re on the same network.
    • Sometimes it takes a few minutes for the new feeder to appear
  5. Refresh the page and you should see that your account should have been automatically upgraded to an Enterprise Account. A new link should appear in the top left of the screen saying “My ADSB”. Click on it!
  6. Find the gear icon on the right hand side of the screen and click on it, then click on the “Configure Location” and “Configure Height” buttons, set those values appropriately, and press “save”.

If the planes are reporting their location over ADS-B why does FA need to know the receiver’s location? Planes without ADS-B transponders do not report their location… but FA can estimate their location using multilateration. They have an more in-depth description of the functionality on this webpage 7. That’s it! Congratulations, you are now feeding to FlightAware.

What can you do with this:

  • PiAware has an interface you can view directly from your Raspberry Pi! Navigate to http://192.168.1.200:8080 (substitute in your own IP address) to see it.
  • You can see stats about your feeder on FlightAware.com/adsb/stats/user/YourUsername
  • If you click on the gear icon like we did in step #6, you can remotly update and reboot your device.

https://discussions.flightaware.com/t/bake-a-pi/19886/5


Railway Logos and the Marching 97

There’s something magnetic about classic railway logos and graphics, they’re bright, they’re clean, they’re bold, and many have been around for decades!

Once upon a time Lehigh University’s unofficial mascot was the “Engineers”. There’s some debate whether this refers to the school’s engineering program or the Lehigh Valley Railroad which passed through Bethlehem and founder Asa Packer was heavily involved with.

Despite a 1995 decision to change the university mascot to the “Mountain Hawk” Lehigh’s band, the Marching 97, stands by the train engineer definition and still wears shirts with locomotives under their uniform.

I’ve made a couple railway-inspired logos for the band. As manager in fall of 2017 I gave out Union Pacific inspired pins at band camp (please don’t sue me, UP).

This year for Alumni Band Day (Nov. 8th) I was itching to make something– I hadn’t even opened up Photoshop since the yearbook was finished in August! Drawing inspiration from the Delaware and Hudson Railway, this graphic is probably more lawsuit-safe as the Lehigh Valley railroad was bought in 1976 (please don’t sue me, Conrail).

One other graphic I’ve been working on since before the 2018 London Trip is a riff on the Chicago NorthWestern logo. It won’t fit on a button as well as the other logos, but maybe it’ll exist as a sticker someday?

Notes

  • I keep an album on Flickr solely of railway graphics I come across. Many of these photos were taken at the Whippany Railroad Museum in Whippany, NJ, which has an excellent collection of exhibits and equipment! The uncredited photos in this post were taken there.
  • If you’re looking for more train-based graphic design inspiration, Reagan Ray has a wonderful collection of good, clean, scans of railway logos on his website.
  • Christian Annyas has written a fascinating blog post on the evolution of these graphics.

Temperature Sensors Part 3: Sensor Hardware

This is post number 3 in a series describing my DIY temperature and humidity sensors.

The Sensor:

Profile view of the sensor

Hardware Breakdown:

The sensors themselves are pretty simple, consisting of only five components.

Not including solder, various lengths of wire, and the perf board that the components are mounted on. I used a Sparkfun Snappable Protoboard ($7.95) as the base for each of my sensors.

  1. ESP8266 WiFi Module ($6.95)
  2. Si7021 Humidity and Temperature Breakout Board ($7.95)
  3. LD1117V33 Voltage Regulator ($1.95)
  4. USB Type A plug ($1.50)

Total cost before tax: $18.35

Prices given are from Sparkfun as of September, 2018

Design Choices:

The goal was a sub-twenty dollar, reasonably accurate temperature sensor that I could place anywhere in my house and forget about.

Data Transmission

I want to store this data in InfluxDB (Detailed in Part I) so I can visualize it in Grafana (Detailed in Part II).

My house isn’t wired for Ethernet– if it was I could solve both the transmission and power problems with Power over Ethernet.

In the past I’ve worked with the Nordic NRF24L01+ radios which are reasonabley priced and have decent range, but I would need some sort of relay that could receive the wireless transmission and send it over TCP/IP to the InfluxDB. Someone has done this, but it seems like extra work when I already have a Wi-Fi network in my house.

So I went with the ESP-8266 Wi-Fi module because I had two laying around. Future iterations may use a different version of the chip.

Power

Some impressive work has been done making the ESP8266 run on batteries for a very long time, but batteries eveuntally need charging or changing.

What I do have lying around though, is a bunch of USB wall chargers that can put out 5V and more than enough amperage which, using a LD1117, can be converted from 5V into the 3.3V that the ESP-8266 and sensor need. The ESP-8266 only consumes 170mA tops and the Si7021 sensor uses all of 150 μA, so the LD1117’s max of 800mA is overkill, but hey, I majored in Computer Science and it seems like a good solution to me.

In summary 120V AC power comes out of the wall, gets converted to 5V DC by the USB wall charger, which the sensor is plugged in to. Onboard the circuit board the voltage is dropped again to 3.3V which the radio and the sensor can use.

Right now I’m only using the USB power and ground lines, but I dream of being able to fit some sort of USB Serial Adapter and a logic level converter so that the ESP-8266 can be programmed directly from the USB port. At the moment it’s a bit of a pain to change Wi-Fi networks, I have to remove the ESP8266, and plug it into a jig to reprogram it.

In Action

Sensor plugged into wall outlet

One issue is that a lot of stress can be put on the pins connecting the USB port to the sensor board.

USB connector broken off of circuit board


Temperature Sensors Part 2: Grafana

Recording temperature into InfluxDB isn’t very useful if I can’t visualize it. Thanksfully, Grafana exists.

This is part 2 in a series describing my DIY temperature and humidity sensors.

Grafana Setup

I have Grafana running on the same webserver as this website, configured with two different data sources:

  1. My InfluxDB server (Currently a Raspberry Pi)
  2. The DarkySky.net plugin for an approximate idea of the outside temperature (Plotted as apparentTemperature on the graph below)

Records:

  • The recorded temperature in my room was 56.09°F on October 19th at 8 AM. Later that day the heat was turned on
  • Since the heat has been turned on:
    • Living room:
      • Max Low: 67°F
      • Max High: 68.34°F
    • My Room:
      • Max Low: 36.65°F
      • Max High: 75.02°F

Takeaways

  • My third floor room is colder than the second floor living room directly below by about 5-7°F on average.
  • Turning on the living room ceiling fan lowers the living room temperature, but does not change the temperature in my room.

Actual Graphs

Below is a “snapshot” of the data my temperature sensors collected between Oct 22nd and Oct 29th, 2018. To make it load quickly I’ve set the resolution to 30 minutes (each point on this plot is the average of the past 30 minutes).

Temperature Graph (Direct)

I’m also collecting relative humidity data:

Relative Humidity Graph (Direct)