Inventory, Even in the Woods

I’m an active member of a local SCA branch. The SCA is a registered non-profit and its branches are much like local chapters, so that non-profit status is inherited. Most SCA branches own some amount of movable property – kitchen equipment, tents & pavilions, wall hangings & other decor, and maybe even a trailer to store and haul it all. Where there’s property, there’s an Inventory!

Taking Inventory the Old Way

In 2019, I attended a “taking inventory” session, where the branch’s property inventory records are compared against the actual items, and the records are adjusted to match (and in some cases, items that went into the wrong numbered box are put where they belong). At that time, the inventory records were captured in a spreadsheet file, with one sheet for every box, plus some sheets for “loose items” and items that are being stored by individuals for reasons of easy access or because they can’t be safely stored in the trailer.

One individual was designated to amend the spreadsheet sheets on the fly, in spite of having paper lists printed out for every box or location. It was torturous, and the general mood was that of rushing to get it done because of that bottleneck. I started marking down notes on the printed sheets, and I also took a bunch of photos (none existed).

Packing Up the Old Way

A few months later, I participated in an event (that’s what the stuff in the trailer is used for!) and helped out with the task of putting everything back into the right box so it would all fit back into the trailer. That consisted largely of guessing which box might be the right one, and visually examining the printed inventory sheet for it to confirm. If you didn’t guess right the first time, check a different box! It took a long time and was very chaotic.

There’s Gotta Be a Better Way!

After that, I was determined to find a better way to manage the branch’s property. I looked at a few self-hosted options, but none of them really fit – they were all too complicated. And so, I decided that I’d see if I could come up with a simpler web app that would meet my local branch’s specific needs and make both inventory and event pack-out a better experience.

Initially, I figured I would use PHP and MySQL to accomplish this, as I had prior experience with both. However, at one point I decided to follow a tutorial to see if I could learn how to use the Django framework. It took me a minute to grok the structure, but yeah, I got it!

Pandemic Project

I checked in my first git commit of the project on September 10, 2020. By the beginning of October, I was able to generate a full set of nicely formatted PDF documents – a full item listing, a document for each box, and a list of boxes sorted both A-Z and numerically. I exported the data in csv and spreadsheet format for backup purposes. I had also given it a name – Mobiliaire.

In October 2020, I accomplished a bunch of tasks:

  • put a demo version online
  • implement a simple search function
  • started adding support for images
  • started adding support for capturing images using a RaspberryPi + PiCamera
  • Released versions 1.0 and 1.0.1

At that point, I had an app that more-or-less worked, but nowhere to take it. My attention went elsewhere and I didn’t do much else with it until July 2021.

Support for More Cameras

In July 2021, I worked out how the app could support most USB webcams, added the code for that, and started planning to abandon a Raspberry Pi-specific fork I’d done (because the ‘picamera’ Python package will scream if you try to install it on not-a-RasPi; plus a few other differences).

Instances for Other Inventories

The app turned out to be flexible enough to be used for managing other kinds of inventory. My spouse has a large collectibles collection documented in an instance of the app. I also used another instance to catalog my fabric stash and sewing patterns. Those happened in September 2021. A good thing came of the collectibles inventory – I was asked to add “edit buttons” to the gallery and reports pages, which I did, for that instance.

Event Sighted Ahead!!

An event was scheduled for April 23, 2022. It would be the first event since Jan 2020. I put my focus in high gear and stuck my head back in a Terminal window sometime around April 6th. I put in over 17 hours of work between April 12 and 23rd. (No data for 6-12 April because I didn’t install Wakatime right away, but I was putting in hours nonetheless)

  • I pulled those “edit buttons” over to the main repository and made them optional.
  • I finished rolling the webcam stuff back into the main repo so I could sunset the RasPi fork
  • I released version 1.1 and 1.2, and created a 1.x maintenance branch for Django 3
  • I upgraded to Django 4 and pulled opencv-python to 4.5.5.x
  • I made a lot of cosmetic changes to the front-end, including standardizing the gallery cards
  • If there’s no camera but the optional “photo contact email” constant has been defined, a modal will display info on how to submit a photo by email
  • I finally deployed an instance on a Raspberry Pi with Apache2 and MySql (previously had only been running on the built-in dev server)
  • I got a bit distracted and fiddled with setting up CI in the repository
  • I then broke that instance by adding a “settings” directory in the project settings folder (oops)
  • It’s okay though – I fixed it!
  • I did dress rehearsals the Saturday and Wednesday prior – brought the RasPi, a configured wifi router, and a Chromebook with me to practice and set it up (and showed it to people)

Event Day went pretty well! Early in the day other staff members learned that it was a quick way to learn where a particular tool was stored. Not a single paper list was consulted during re-pack. We were done and ready to close up an hour and a half after the event closed. In the past that could be 9 or 10pm.

What’s Next?

Inventory Day is next up. Not scheduled yet, but hopefully, they give me some time – there’s a mechanism for reporting inventory checks, but it’s not optimal. I need to build the front-end features that make it possible to scroll through a box’s list of items and click checkboxes for each item seen, then click a “submit” button when done.

At that point, it will be possible, given the availability of multiple notebook computers or tablets, to run multiple teams at once. Each team grabs a box, checks the contents, makes notes, submits the form, repacks the box, marks the physical box as “done”, and grabs another box.

This upcoming inventory day is going to be a bit more complicated, though – we also need to photograph most of the items. We need individual photos, or in the case of multiples, a photo of the multiples all together. These photos are important because they are an integral part of the process of repacking. A visual confirmation that the item in your hand is the item in the search results is needed (some similar items can be found in more than one box due to the need to play Tetris and make everything fit).

The last piece will be to label everything that can be without being obvious to guests, preferably via marker or etching. Because Django is Django, the URLs are RESTful, so any Item can be viewed by appending its ID to the end of the items url.

You Made it This Far, and You Still Want One?

You can git clone it from the Mobiliaire repository on Gitlab and give it a spin. Check the Wiki there for some more detailed setup instructions. If you get stuck, please submit an Issue so I’ll know I need to refine the documentation.

What was that About Woods?

Oh, right, the Woods. With a machine loaded up with Mobiliaire + local (vendored) bootstrap, JQuery, and DataTables libraries + an optional wireless router, your event staff can have access to the inventory system independent of whether the event site has Internet access, and independent of whether there’s even good cell phone signal at the event site. All you need from the event site is a working power outlet to plug your gadgets into. Or a generator. Whatever, I don’t know your life.

The database is incredibly easy to transfer from instance to instance with Django’s ‘loaddata’ and ‘dumpdata’ functions. The resulting files make excellent backups.

Image: “Rhuddlan Castle” by Jeff Buck is marked with CC BY-SA 2.0.

DIY-ing My Way to Better Ventilation

If you scroll back two posts, you’ll find one about COVID-19 risk mitigation strategies. One of the items in that post was DIY CO2 monitoring – based on research that showed that CO2 concentration in an indoor space correlates with infection risk. Since I wrote that post, I’ve actually built two DIY monitors, and they’re being used on a weekly basis to support decisions around when additional ventilation (opening windows, using fans to circulate fresh air) is needed. Note that this measure is in addition to having all participants wear masks 100% of the time and running an inexpensive, ad-hoc air filter in one of the two spaces used.

From Humble Beginnings…

I already had both a MagTag and a PyPortal, two small Internet-enabled devices you can program using a specialized version of Python. I started out making just one purchase: a Qwiic/STEMMA compatible CO2 Sensor breakout board plus a cable to connect it. When the sensor and cable arrived, I discovered that, while I could connect to the MagTag, I didn’t have the correct cable to connect the sensor to the PyPortal, which is really what I wanted – for the color screen. Back to the online cart I went for more spending!


While I waited for the correct cable to arrive, I gave the sensor a spin using my MagTag, which is presently employed as a small weather widget. Since it was already reporting useful information, why not add a little more, right?

The Adafruit SCD-30 sensor reports CO2 concentration, relative humidity, and ambient temperature. You can get better accuracy from it by regularly feeding it the current atmospheric pressure in millibars. If you have access to a cylinder of calibration gas, you can use that to calibrate it. Otherwise, it has a “self-calibration” feature where the sensor will adjust itself as long as a) you allow it to run continuously and b) you give it access to fresh air at least once every 24 hours. This works because the average concentration of CO2 in fresh outdoor air is approximately 400ppm. The sensor will keep track of the daily low concentration and make adjustments based on those readings after several days of continuous operation.

The first thing I did was add the reported CO2 concentration and ambient temperature to the weather widget display. It was a tight squeeze, but I was able to fit both in at the end of the location name. Ok! I got the hang of using the SCD-30 Python library to fetch information. That’s a great start.

And then, Delivery Day!

Once my correct cable arrived, I moved the sensor over to the PyPortal and began working through other tasks. I hadn’t yet learned how to use CircuitPython to position and display text, so I did that next. By the time I checked my script into a shiny new git repository, it would wait for the sensor to report that a reading was ready, then pull the CO2, humidity, and temperature readings into variables. It would convert the temperature to display in degrees Fahrenheit, and display all three metrics on the screen, in green if below 1000ppm CO2, in yellow if between 1000 and 1500, and in red if above 1500ppm. I added in changing the color of the PyPortal’s neopixel LED a little later on.

Just having a CO2 reading wasn’t enough for me, though! I ordered a pressure sensor and a RTC board, both also Qwiic/STEMMA compatible, and some more cables. I wanted a system that was accurate, that could work without Internet access, and that could support writing sensor readings into a log file with a timestamp for analysis later.


As I was nearing completion of my PyPortal script, I discovered an issue: it would boot up just fine if I connected it to my computer (via USB; that’s how the executable scripts are accessed), but would boot up very slowly or not at all if I powered it by an electrical socket adapter (“wall wart”). I did a bunch of testing and consulted with the PyPortal experts on the forums, and finally, the source of the trouble was identified: the PyPortal, by default, supplies 5v to the JST I2C connector. If one is going to run the kind of sensors I was running, the power level needs to be shifted to 3v3 (by cutting a PCB trace and soldering two adjacent pads together). That isn’t something I wanted to do to my PyPortal, so I decided to pivot to another piece of hardware I already had.

Do you like Pi?

Until recently, there were six Raspberry Pi boards in my house, ranging from Model B Rev 2 boards (2012 says hi!) all the way to an 8GB Raspberry Pi 4. Each one is host to one or more locally-running self-hosted services, including RetroPie, Plex, PiHole, WordPress, Grocy, Django, Prometheus, and Grafana.

I ordered a SparkFun Qwiic HAT- an adapter that seats onto a Raspberry Pi’s GPIO pins and has four Qwiic connectors. I decided to use my Portable Pi, a Raspberry Pi 3 + 7-inch official touchscreen housed in a SmartiPi enclosure with separate power input for the screen. When I bought it, I also purchased a Pelican case with customizable foam so it could travel safely. It would be just the thing to bring along with me to the local weekly SCA fighter practice and art night.

a 7-inch screen displays the output of a python script that reads data from CO2 and pressure sensors, and then displays that information on the screen.
CO2 Monitor Script running on a portable Raspberry Pi computer

I dropped a copy of my PyPortal script, installed the Blinka Python library, and got to work modifying the script to work with the 7-inch touchscreen using the Pygame library, which also features touchscreen support. I came up with a script that displays the CO2, temperature, humidity, and pressure, with red/yellow/green color changes at breakpoints defined in the script, and logs everything to a csv file.

Don’t Speak Too Loudly, or Everyone Will be Wanting One

Yep. I talked to people about it. I talked to local SCA people about it. I talked about it way back when I was still working out the script with the PyPortal. “How much would it cost to build one?” they asked. (The answer is, somewhere between $130 and $160, for a build with a color screen, depending on what sizes and types of parts are chosen.)

The local chapter can vote to spend money on such things, and they did. So I ordered some parts. I went with the following configuration:

  • Raspberry Pi Zero W (with Header)
  • 2.8″ mini TFT touchscreen
  • SparkFun Qwiic HAT
  • GPIO splitter (seats on the Raspberry Pi’s GPIO and splits off two sets of connected GPIO pins – one for the touchscreen and one for the Qwiic HAT)
  • Adafruit SCD-30 CO2 sensor breakout with Qwiic/STEMMA ports
  • SparkFun Qwiic LED Stick

I supplied a micro-USB cable for power because I have loads of them around the house. After I complete the configuration, I’ll 3D print an enclosure to hold and protect it all.

Of course, a different screen means a different Python library for the display! So I needed to rework the script again. While I was doing that, I was also asked if it can do audible alarms (it totally can with minimal fuss if you have a Bluetooth speaker handy!) so I added that capability. I wanted to be able to easily import logged data into a MySQL database for data display in Grafana, so I set up a second log type. I added command line flags somewhere in there – you can turn debug on (or off, depending on what the default is), enable Grafana logs (off by default, you need to supply a location name for the log), pass in a local air pressure reading if you don’t have a pressure sensor attached, specify a log filename, and turn regular logging on/off (depending on the default).

Add a Little Spark

An animated GIF composed of a time-lapse photoset illustrating the behavior of the sparkline.

Most recently, I added a sparkline history – the last 18-25 CO2 readings are displayed across the screen between the “PPM” label and the temperature / rH / pressure label. This is not a true graph, as the column heights are freshly calculated every time a new reading is added and the oldest reading is discarded. A “zero” column height is assigned to the lowest number in the set and a “100” column height is assigned to the highest number in the set. The remaining numbers are assigned varying column heights based on their relative position between the high and low numbers, and columns are Unicode characters in the Block Elements group.

The sparkline will show you the trend over the last minute or so.

Eventually, I will build a custom enclosure for it to protect the delicate parts against damage.

Cool, How Can I Get One?

The short answer is: you build it yourself. If you choose the exact same configuration as one of the builds I’ve done so far, you’re in luck – I’ve posted the entire CO2 monitor git repository on my GitLab with an Open Source license. If you choose something different, you may be partly or completely on your own.

If you’re located in Harford or Eastern Baltimore Counties in Maryland, or York or Lancaster Counties in Pennsylvania, I’m available for hire to do custom builds at $75/hr plus the cost of parts and parts shipping. If you just want advice, you can get that for $35/hr.

The graphical output of this script can be piped out to an external display via HDMI. It can be modified to work with only a controller and an array of multi-color LEDs, a tiny OLED screen, or e-paper screens. Add a LiPo battery and a battery management board and you’ve got something very portable you can carry around with you for air quality sampling! Remember when choosing hardware that your chosen configuration is not guaranteed to work with my scripts out of the box until they’ve been tested, and even then, things can and do go wrong (usually it’s fixable and often not terribly expensive).

This is a great project for kids – younger ages will need assistance, but teens will likely be able to do this unassisted. I’m available for tutoring in the same locations as above, but a parent or guardian must be present at the location at all times.

One Last Thing

Remember that Raspberry Pi count I mentioned earlier? Today there are 8 of them in my house. The two new ones are Zero W models, one with headers, one without. One was purchased for this project, the other for an unrelated project).

10 Micro-electronics Projects that Aren’t Robotics

There’s more to educational/hobby micro-electronics than building robots.

If you or your kid can’t muster up excitement about robotics, go take a peek at these 10 projects. I’ve included a variety of different projects that do different things, run on different platforms, require different knowledge levels, and have different price points. Some of them also include the opportunity to learn about enclosure fabrication.

1. The Pimoroni Grow

This handy widget is a Raspberry Pi “HAT” (that stands for “Hardware-On-Top”). It connects to a Raspberry Pi’s GPIO pins, and is compatible with any Raspberry Pi model that has 40 GPIO pins (so, not the very earliest Pis). It is easy to connect to a Raspberry Pi – you just (carefully) plug it in so that all 40 pins are seated in the Grow’s GPIO socket. You can separate the two boards later if you need to.

The Grow uses connected capacitive touch sensors on custom-designed plant marker sticks to detect the moisture level in potted plant soil, and then gives a visual indication of moisture level for up to 3 sensors.

2. SparkFun OBD-II UART board

Learn how to read vehicle diagnostics over a serial connection. Those with more experience in micro-electronics should be able to, for example, create a portable version that runs on an Arduino or Raspberry Pi, features a screen and selection options, is rechargeable, and has a custom enclosure.

3. PiHut RasPi TV HAT

Feed digital OTA (broadcast) TV into this board while it’s plugged into a Raspberry Pi and you can stream broadcast TV to other devices on your network.

4. MagTag Pet Feeding Clock

Does your pet tell lies about not having been fed yet? This project is for you!

You can easily program this lightweight smart display to update the date and time your pet was last fed by pushing the left-most button. While it’s not included in the tutorial, a more advanced version of this would give you the ability to track most-recent mealtimes for up to 4 pets (or food plus 3 different medications).

5. Pwnagotchi WiFi Pentester

Test your home network’s wireless security.

Reminder: hack responsibly.

6. Digital-to-Analog Audio Conversion

Have you found a nice pair of old analog speakers at a yard sale? Give them new life with a Raspberry Pi HAT from HiFiBerry.

While you’re at it, you can use the same Raspberry Pi board to also host a local streaming music server using Jellyfin. Note that you will need to have music files stored locally.

7. Environment Sensor HAT

There’s no specific project tutorial for this one, but similar tutorials are available, and part of the lesson can be adapting to using different hardware. This HAT would be great for an offline local weather conditions display. It even has onboard motion sensing for those of you who live in places where earthquakes are frequent. For even more experienced programmers, how about including weather prediction by data analysis?

9. Binary Clock Soldering Kit

This Binary Clock project is a soldering kit that also presents an opportunity to custom fabricate a case. It comes with a printed circuit board, board components, and a pre-programmed IC, so no programming skills are needed for this one.

10. E-Paper Badge

Show your name (or whatever else you want) on a small e-paper display you can wear. You can add magnets to the back to attach it to your shirt or connect it to a badge lanyard (tip: make that easier by adding a bezel-type frame with lanyard loops).

Where to Next?

Once you learn the basic concepts of connecting peripherals and programming logic, you can take disparate components and make something completely new! There are quite a few hobby electronics suppliers out there these days, with lots of platform and form-factor options (we didn’t even get into soft circuits, which are electronics built into clothing using conductive thread and sew-on components!). Browse those tutorial sections, follow makers on Twitter, and maybe even write a tutorial of your own!

Indoor COVID-19 Mitigation Strategies for Fall 2021

You know it’s coming: you’re going to be guilt-tripped into attending a family shindig during a major holiday during the part of the year (in the Northern Hemisphere) where being outdoors isn’t a comfortable alternative. And maybe some of your family members are refusing to be vaccinated, while others may be immunocompromised. It is a pickle, but there are some things you can do to lower the risk of those gatherings turning into super-spreader events. I don’t know about you, but even though I’m vaccinated, I don’t relish needing to spend an entire week sick, miserable, and in bed!

Risk mitigation is when you take an action or put a control in place that reduces the risk of bad things happening. Mitigations are rarely 100% effective, but they don’t need to be, either. When you combine two or more risk-mitigating actions or controls, you combine the risk-reducing effect they have. Combining mitigations that work in different ways (for example, providing both shade and water to people working outdoors in hot conditions) works better than each action alone does.

1. Everyone Wears a Mask

Pick a mask, any mask. As long as it fits well and is worn properly, a mask can reduce the number of viral particles ejected into the air from your nose and mouth while you are breathing, talking, singing, yelling, coughing, or even sneezing. By reducing the number of viral particles that make it into the air, you also reduce the total number of viral particles in the air.

2. Everyone Wears a (K)N95 Mask

Cloth and surgical masks are great at blocking large droplets. Certified N95 masks and their untested-but-possibly-easier-to-find cousins KN95 masks can stop fine aerosols. They also are much better at keeping air from leaking out via the edges – and they don’t tend to push against your nose the way cloth masks do. Make sure you get the kind that doesn’t have valves – those aren’t as effective because they don’t block viral particles and fine aerosols on the way out. An added benefit is that this type of mask works in both directions – it can help keep viral particles out of your respiratory system (though they won’t keep the virus out of your eyes).

3. Monitor CO2 Levels and Cross-ventilate When Necessary

Researchers at UC Boulder figured out that CO2 concentrations in a space correlate to the risk of covid-19 spread. Properly ventilating indoor spaces to reduce viral spread is a concept that dates back at least to the 1918 pandemic. The tl;dr is that you can use a CO2 monitor to tell you when you need to throw open a window or two and let in some fresh air.

However, a pro-grade CO2 monitor may cost you several hundred dollars, something a lot of people just don’t have. DIY electronics hobbyists have an alternate solution for you, though: DIY CO2 monitors.

There are a variety of plans and tutorials available, all the way from source-all-parts-yourself to programmable gadgets (such as the Raspberry Pi) that just need a CO2 sensor plugged in.

4. Add Ad-hoc Filtration

The EPA recommends increasing ventilation system airflow in both homes and institutional spaces to reduce the spread of covid-19. When modifying an existing ventilation system is cost-prohibitive, or you don’t have any control over it, an in-room filtration solution can help out. Some air filters can be very pricey – but some smart people at an air filter company – working with an environmental engineer at Portland State U – came up with an accessible, inexpensive, high-capacity solution: a 20″ box fan and some 20″ x 20″ MERV-13 rated air filters. The design calls for 5 filters, but if one side of the resulting cube is going to sit flush on a flat surface, you can probably do just 4 filters.

5. Maintain Adequate Relative Humidity

The consistently cold temperatures of winter cause relative humidity to drop. Viral particles (of all kinds) thrive in drier air. The solution? Monitor and maintain an indoor relative humidity of 40-60%. Your respiratory system will be happier. It is also harder for viruses to infect people who have sufficiently moist respiratory passages. Some DIY CO2 sensor modules will also report temperature and relative humidity, so if you’re going to build a DIY CO2 monitor, you may be able to add in humidity reporting!

In Conclusion…

The covid-19 pandemic is far from over. Life tries to go on in spite of that, but we can all take part in reducing covid transmission by adopting mitigation strategies. Don’t think your family will go for it? Try making your attendance contingent on these controls being put into place, and stick to that. Or, host the next one, and make everyone else’s attendance contingent on their compliance. Use FOMO to your advantage, here.

Image: Yoga in a Yellow Suit by Cottonbro

How to: Anki SRS + Learning Shorthand from a Manual = Magic

I’ve wanted to learn shorthand for a long time. In the mid-oughts, I bought a physical copy of The Gregg Shorthand Manual Simplified – Second Edition by John Robert Gregg, Louis A. Leslie, and Charles E. Zoubek. At the time, I tried following the book but it didn’t take. The book sat on my bookshelf for more than 15 years and moved across the country twice in that time.

Discovering Anki

I read Gabriel Wyner’s Fluent Forever last Autumn. This book provides specific instruction on how to leverage spaced repetition systems (flashcards with a system for how often you should see each card) for learning languages. I am in the midst of rebuilding my French language vocabulary using Anki, a computer-based spaced repetition system mentioned in Gabe’s book. While I was adding my first cards to Anki, it occurred to me that I might be able to use Anki to finally learn shorthand at the same time, so I loaded in the first lesson and gave it a shot. I now have a shorthand “vocabulary” of about 250 words and brief forms and have entered all of the individual words & brief forms in the Gregg book up to and including Lesson 11, with over 250 words & brief forms (566 cards) not yet seen.

The purpose of this post is to go into detail on how I set up my Gregg shorthand Anki deck. You could use any shorthand system you like, but you will need access to images of letter, word, and brief form outlines to compare against.

Setting Up Anki for Learning Shorthand

Let me begin with an important bit of Anki terminology: a note is an information pair – a question and an answer. From one note, you can have Anki generate one or more cards, which is what you’ll see when you review. If your question/answer pair is structured to allow reviewing in reverse (so you see the answer and have to recall the question), you can have Anki automatically create a second card from the same note that does this.

Repurpose as Needed

In card templating, I am cheating a bit and using the “Picture Card” templates that are available for free download from the Fluent Forever website’s “Gallery” page. These card templates are set up to produce two to three cards per vocabulary item “note” (letters, words, brief forms, practice sentences, etc). The note creation template has five fields: word, picture, information, pronunciation, and spelling-check. This template can create the following cards: a card that shows you the word and you must recall what is in the “picture” field and speak the word correctly; a card that shows you the picture and you must recall what is in the word field and speak the word correctly, and; a card that shows you the picture and plays a recording of the word being spoken (you provide the recordings here) and you must correctly spell the word. The “check spelling” field is a y/n question that defaults to no.

Let’s Get Down to Brass Tacks

So how did I leverage this card template for shorthand?

  • I extracted images of the example shorthand outlines in the book:
    • I used my phone to take photos of the shorthand outline examples in the book, starting with lesson 1
    • I copied the photos over to my computer and used the Windows Snipping Tool to collect grabs that only include the shorthand outlines – one for each long-hand vocab item.
    • For letters that are similar (s/f/v, r/l, k/g, etc), I took a grab of the entire example row, blotted out the alpha identifiers, and saved multiple copies, each with an arrow pointing at one of the shorthand outlines.
    • Save yourself some future headaches and name your snipped images after the words they represent, and put them into either a single folder or a set of folders organized by lesson.
  • I sat down with Anki and my book and added notes in the order that letters/words/brief forms appear in the book. You can drag/drop images from a folder into any Anki field if that makes it easier.
  • I put the long-hand letter, word, or brief form in the “word” field. Letters and brief forms are labeled as such in this field to differentiate cards (because most letters are also used as brief forms). I add the same label to the picture field as well because I also need to know this information when shown the reverse card.
  • I dropped the matching image into the “picture” field
  • In the “extra info” field, which only appears on card backs, I included a glyph of the letters/sounds used and any section notes for that outline type. I formatted the glyphs like this:


[th-e-r-o] the e represents the obscure o/u sound

  • Each individual letter/sound in the glyph is separated from the others either by a dash (most of the time) or a space (for disjointed strokes).
  • And finally, I add some tags at the bottom.
    • Each note in this deck is tagged “gregg”
    • Each word is tagged “words”
    • Each letter/sound is tagged “letters-sounds”
    • Each brief form is tagged “brief-forms”
    • Each item from a particular lesson is tagged with that lesson number.
    • Each comprehension sentence is tagged “reading-comprehension”
    • Each non-alpha symbol (numerals & punctuation) is tagged “symbols”

Time to Learn!

Once you’ve loaded a bunch of notes, it’s time to study! I have this deck set to introduce 10 new cards each day I study. Because it’s spaced repetition, I also review the cards that are due at the same time. On average, I see 5 reviews each day (but remember I’m studying other decks, too).

If you add notes in book order, you’ll also see them, new, in the same order. If you mess up and add them out of order, you can reorder them in the browse view. This is where having lesson number tags is valuable.

For each due item, I am either presented with longhand or shorthand. If I see shorthand, I must correctly identify the letter/word/phrase (and remember, if it’s a letter or brief form I’m supposed to be identifying, there’s a label with the shorthand image indicating that). Conversely, if I see longhand, I must take a pen and paper and accurately write out the shorthand. As I progress, I increase the threshold at which I find my shorthand outlines acceptable – because this involves learning new penmanship, not unlike learning calligraphy.

Be the Judge of Your Own Work

After I give or write my response, I click the answer button and am shown the reverse, which includes my letter/sound glyphs and notes about how certain sounds are written. I rate the card’s difficulty: if I got it wrong, it gets reviewed again the same day; if I had to think about it or my penmanship wasn’t great, it gets rated “hard”, if I got it close enough, it gets rated “good” and if I got it quickly and very right, it gets rated “Easy”. Those ratings determine when I will next see that card (Anki shows how much wait time each button adds) and you should do it in whatever way works for you because you are the only person who matters in this situation.

At first, I was also including the reading practice sentences, but that became tedious both in adding new cards and writing out the sentences, so I suspended the writing cards, left the reading comprehension cards, and haven’t added any more – especially as the comprehension examples grow in size from sentences to entire passages.

What I Might Do Later

For reading comprehension exercises, I may just create single cards that reference exercise numbers and keep the book nearby. I might record or download clips of vocab words being spoken and enable “spelling test” card creation to help train myself to write what I hear. Or, I might go find some podcasts with spoken English recorded at a slower pace intended for English-language learners and use them to practice writing what I hear – and then set a delay timer on those transcriptions for me to use for reading comprehension later on (because it’s important that you can read what you’ve written, amirite?). Lesson 11 isn’t even 1/4 of the way through the Gregg book, so I may hold off on transcribing live native speakers speaking at normal speeds, and before I start practicing on those, I might go and transcribe uncaptioned videos played at half-speed – and after I transcribe my transcription into longhand, I might just post the transcription as a comment on the video, because why not also do some volunteer work that helps people?

Grocy in the House

I installed and began using Grocy a few days ago. Grocy is a household food inventory manager application with lots of bonus bells and whistles. It is available in multiple forms: a desktop application, self-hosted PHP (flat file SQL by default, which I assume you could change if you wanted to), or Docker container.

This post memorializes information about how I have set my instance up for my household. I’m running the PHP/SQL version on a Raspberry Pi on my own local network. We don’t need access outside of our local network, so no port forwarding is set up at this time.

Display of Information

Grocy helpfully makes it easy to print out lists of items grouped by location, and I’m making good use of that by posting a list at each location. This is especially helpful with freezers and refrigerators – as long as you keep the posted list sheets updated, you can see what’s inside without opening the door.

I’ve also found that we have quite a few food items that are way past due. Some have even been moved cross-country twice. So I printed out a list of everything that is past due, and wrote, ‘The “Most Wanted” List’ across the top in red marker and posted it on the pantry door, where most of the items on the list reside. I aim to refer to that list regularly and work on using up those items whenever possible.

Kits and Mixes

Any product you take and combine with staple ingredients like water, milk, butter, or fresh meat to make a meal, side dish, or dessert is included in this category. This can also be complete kits with no additional ingredient requirements. This allows me to filter just those kits/mixes when doing meal planning.

  • Use “Kit” or “Mix” at the beginning of the name for sorting. 
    • Kits have multiple separated ingredients (packets, loose pasta or rice, etc)
    • Mixes have all the ingredients already mixed together except what you add
  • Add to “Main Dish”, “Side Dish”, or “Dessert” product type, as appropriate.
  • Product measuring unit is any kind of “each” (box, can, bottle, bag or just “each”)
  • Exception: canned soups have their own category, and should be named with a leading “Soup,”

Products Used “All at Once”

Any product you can reasonably expect to use all at once (canned products, single-serving snack items, etc)

  • Enter in “each” (or similar appropriate) units
  • Multipacks should be entered by individual pieces on purchase
    • Example: fruit cups entered in “fruit cup” units, Lipton Noodle Soup in “packet” units
    • Price will be “total purchase” – ie the cost to buy the pack, while you’re entering multiple “items” that were purchased as part of the pack into the inventory. Enter the entire pack, then “consume” one if you are using one right away, or the price calculation will be off.
  • Single-serving items that come in multiple flavors can be grouped together under one product name, with “multiple flavors” in the product name and every barcode in the barcode field.
    • As long as the goal is to have a minimum quantity in stock no matter which flavor (you can always examine the actual items in the pantry to inform your shopping list)


Because we consume condiments in very small increments, we will treat them as whole items until they suddenly aren’t.

  • Enter into system as “each” counts or equivalent
  • “Consume” when you throw away the container
  • Product type of “Dry Condiments” and “Liquid Condiments” (semi-solids like jelly are classified as liquids in this instance – the “dry” classification is for powdered condiments)
  • If you allow partial units in stock, you can “consume” 0.5 unit when you are approximately halfway through a particular product, which should get the system to identify the product as “under quantity” if the number of units you physically have are equal to the minimum quantity. And that gets the product on your shopping list 🙂

Bulk Products Used Incrementally

Products like flour, bread crumbs, sugar, rice, and beans are set to be managed by weight. 

Whenever possible we store these in permanent containers. 

  • We weigh the container to measure tare weight and mark it somewhere on the container for future reference.
  • We add the tare weight to the master data entry for the product.
  • When we use the product, we weigh the container after we are done measuring out what we’re going to take and enter the new total weight into the “consume” form. The system will subtract the proper amount.
  • When we refill the container, we weigh the container after we have added the new product and enter the new total weight into the “purchase” form. If there is product left in the package, set the package on top of the container and weigh them together. Use up the product in the package first until it’s gone. 
  • Wait to refill until most or all of the new package contents can be added at once.
  • When you physically purchase a new package of a product, but you can’t add it to the container yet, write the price and store name on the packaging so it can be entered into the “purchase” form later. If you still want to track it, you could create a master data product entry for the original packaging unit. When you’re ready to transfer, you consume 1 unit of the product that has the “each” quantity unit, and then you proceed with the “purchase”.
  • Bulk products that have a “basic recipe” printed on the packaging (ex rice, quinoa, couscous) have those ratios/instructions copied into the product’s description box so that if I’m transferring the product from its original packaging to a reusable container, the instructions are preserved and easy to find.

Fresh Meats and Bulk Cheese

These are tracked by the ounce. Tare weight enabled where appropriate (ie bulk shredded cheese or whole blocks that will be used incrementally)

  • First In First Out is especially important here to reduce freezer burn
  • When repackaging meats, write the name, date, and weight on the new packet
    • The “purchase” entry will be the weight and total cost of the purchased quantity of meat. Enter weight in pounds, my copy of the application is set up to convert that to ounces automagically.

Locations, Transfers, and Perishables

Grocy automatically tracks “use by” expirations for perishable items and adjusts the “use by” date whenever you transfer an item into or out of a location that is marked as a “freezer”. When you move anything from one location to another, the system also needs to be updated. This can be recorded on the posted sheets – just write:

  • Item name, from, to, date (important only for perishables), quantity

If you open an item that is shelf stable as long as it is unopened but has a “use by” once it is opened, record the date it was opened, and transfer from/to locations if it was also moved.


Spices and dry seasoning mixes are counted as each bottle/can/jar and consumed when we discard the bottle. All are set to minimum stock of 1, and allow partial, so that when a jar is running low, it can be updated to a value that is less than 1 to trigger the shopping list.

Recipes and Meal Planning

Initially, I started putting meal/side “kits” into Grocy as “recipes” that called for the kit and the additional ingredients needed. I stopped doing that once I figured out that you can add recipes or products to the meal plan. So, now I add the kit and its needed ingredients to the meal plan and don’t bother with the recipes for those (I’m still adding recipes that don’t involve kits).

All told, I think this system will work out well for me. I think I’m going to have to go poke at the backend to see how easy it would be to backup the database. I have been using a declawed CueCat scanner as my USB scanner, but I also have put a more modern $25 USB barcode scanner on my wish list for later. I may even go as far as getting a Raspberry Pi Zero W, a 7″ touchscreen, and a case for them so I can install a scanning station right in the kitchen. Finally, as a stretch goal, I might fork the project and design a separate UI for small touchscreens like the 7″.

Building a Better (and free!) Equipment Inventory – part 2

Since I published my last post on this topic, I have developed the entire application and released version 1.0!

A demo is available at

You can grab a copy at If you are going to run the app on a Raspberry Pi computer, there is a RasPi specific fork available at

The main application allows administrators to enter and edit items, boxes, and warehouses individually via a user-authenticated admin site. Admins can also upload data in csv format for easier bulk adding.

The front end displays database information organized into two distinct view types: browse and reports. The browse views display warehouse, box, and item information on tiled cards with associated images (if available) and human-friendly names, descriptions, values, and keywords. You can begin at any level and drill down from warehouse to box to item. The Items browse view includes a keyword filter that allows you to limit displayed cards to items matching the selected keywords.

The report views present the same information in a tabular format and allow exporting of the tabular data to PDF, csv, Excel, or local printer.

The application is built with a lack of Internet access in mind – you can install it on a portable or semi-portable device, transfer the database and static files for your inventory, import the database, and bring it to your event or inventory day where it will function whether or not reliable Internet access is available.

The RasPi fork has built in support for capturing item photos using the Pi Camera – and when you activate it via the “take a photo” link on any item, box, or warehouse detail page, it will automatically name the image file with the associated item, box, or warehouse ID to help the administrator associate the resulting photos with the correct item, box, or warehouse without needing to have an in-depth familiarity with the inventory items.

This application can run on any device that supports Python 3.6 through 3.8. That includes Windows and any device on which you can install Termux or an equivalent terminal application.

Tested on Raspberry Pi, Ubuntu, WSL Ubuntu, and Samsung Galaxy Note 8 (with Termux). If you get it running on another platform let me know!

Submit your tickets at the github repositories.

Building a Better (and Free!) Equipment Inventory

My local SCA branch, like most branches, owns property. The group collectively owns a cargo trailer, kitchen equipment, tournament field equipment, navigation signs, and more. All that *stuff* has to be documented.

Right now, that documentation is in the form of a spreadsheet, with one sheet for each numbered box in the trailer, one sheet for items stored loose in the trailer, and one sheet for each member who is holding items for the group (because they are frequently brought to practice). It is messy and doesn’t facilitate pulling statistics (for example: the total replacement value of all items should the trailer suffer a major catastrophe). It also doesn’t currently produce nice (or uniform) hard copies.

Currently, a hard copy of each sheet is inserted into each corresponding box, allowing event staff to find items and later repack the right items into each box. Finding an item requires leafing through all pages of the full inventory and scanning down each list until the desired item description is found. Repacking works in a similar fashion – it’s chaotic. I think I can improve this process by creating a web application that is portable enough to be installed on a Raspberry Pi board and served up via wifi at a site that has no native wifi available.

Yes, commercial inventory web-apps are available. However, they cost money, are often more complicated than is necessary, and may require server environments that groups don’t have access to. This application will be written in php (and maybe some javascript) with a mySQL database. All of that software is available for free and it isn’t difficult or expensive to spin up a suitable hosting environment.

As I work through creating this application and its database backbone, I am going to use this blog to talk about features I build (or plan to build) to remind myself of those good ideas for later. I will also use it to share this information with other members of my branch.

When the application is functional, I will advertise it within the SCA – first within the East – for other groups to clone and use the base code, which will be hosted at an online git repository.

Right now, today, I am still building out the database. I’m using this as an opportunity to improve my database structuring skills. I spent a little time populating the database with some item records so that when I write my SQL queries for the app, I can test them and get real and meaningful query results.

After today’s data-entry session, I have already identified another wanted table: consumable item use reports. The property list contains consumable items – plastic storage bags, trash bags, soap, sponges, latex exam gloves, bandages, alcohol wipes – you get the idea. When a consumable item is used, a staff member can report that within the application via a button on the item’s information page. The button brings up a form, item ID, name, and description pre-filled, with new entry fields for the quantity used and comments. A later option can be a quick-fill tabular form for entering multiple reports (when the staffers keep track using a paper tally and the entry is done later).

Additionally, some of those items have expiration dates. I want to make a report that lists all items that expire, shown with their expiration dates, optionally by order of expiration date to allow timely replacement of expired consumables. This report should be short since it is composed primarily of items in the First Aid boxes, but it’s also a very important routine maintenance task.

Catch up with me later and if you haven’t seen any posts here about this recently, ping me on Twitter @cordelya.

Recently in Making Things – May & June 2019

three glass beads on steel mandrels

I’ve made quite a few things in the past month or so. Here are some highlights.

Adulting 101: Investing

This is part one in a series of posts where I gather resources on Topics you may have Missed Out on while growing up.

Unless you grew up in a household that participated in “investing”, you may not know what it’s all about or how it’s done. It probably looks complicated, difficult, and unreachable – especially if things like investment minimums are personal stumbling blocks. Here I’ve rounded up a series of resources to help you learn how to do it.

From Reddit’s r/PersonalFinance:

Reddit has an awesome subreddit all about Personal Finance. Below are some recent (as of this post’s publication date) threads from the PF subreddit on the topic of investing.


Head on down to your local library for these. If you find one particularly useful and find yourself making return trips to re-read or check it out, that’s when you should think about buying your own copy.

Blogs and Podcasts

Listen up! Here is a small collection of blogs and podcasts focusing on beginner investing and investing when you’re starting with very little.

Wrap it up!

While you were out learning about investing, did you find something awesome that other newbies would find helpful? Share it in the comments and if it is indeed a goodie, I’ll add it to the list and give you credit for finding it!