2014-11-01

Updating My NaNo Novel

Today I woke up eager to get cracking on my Novel for National Novel Writing Month. Although the site didn't crash this year, booyah!, there was a rather persnickety issue with deadlocks in the database that was keeping participants from updating their novel word count. Brutal

After a few hours of debugging and some quick/dirty hacks, and then a more robust fix, the servers were chugging along at a fairly good clip and I could finally get down to typing some words.

Hold on a sec! There is no way that I'm going to do a bunch of typing and then copy/paste my words into the NaNoWriMo word count checker every time I do a bunch of writing. To be less dramatic, this morning I was trying to take advantage of the new wordcount Write API when I became aware of the database problems.

Anyway, surprise surprise I am using Geany to write my novel, and geany has a nice feature where one can define a project and set build commands for that project. Now I know what you are thinking, a static text file doesn't need a build command, and while this is true, I have decided to use the build command to run a script that will count the words in my novel and upload the count to the NaNoWriMo server.

My workflow goes like this:

  1. Type type type my novel
  2. press F8 to run the 'build script'
  3. always skip step 3
  4. rejoice at the simplicity

The script is a quick bit of Ruby with some wrappers around some shell utilities.

Enter The Ruby

#!/usr/bin/env ruby
require 'digest/sha1'
require 'net/http'

#--- config ---#
name 'MY_NANO_NAME'
secret_key 'MY_SECRET_KEY'
novel_file 'MY_NOVEL.txt'
count_file 'count.txt'

#get the word count from the novel
wc `wc -w #{novel_file}`.to_i

#get the last recorded count
lrc `cat #{count_file}`.to_i

#is the word count greater than the last recorded count?
if wc lrc
  #update the lrc
  `echo #{wc#{count_file}`
  #create the hashable string
  hs "#{secret_key}#{name}#{wc}"
  puts hs
  #hash the string
  hashed Digest::SHA1.hexdigesths )
  puts hashed
  #prepare the data
  data = {namenamehashhashedwordcountwc}
  #create and send the request
  http Net::HTTP.new('nanowrimo.org')
  request Net::HTTP::Put.new('/api/wordcount')
  request.set_form_datadata )
  response http.request(request)
  puts response.body

end

For easier copy/paste, the code is available at http://hoof.jezra.net/snip/oq.

Now quit reading, and go write, or read.

Comments
Name:
not required
Email:
not required (will not be displayed)
Website:
not required (will link your name to your site)
Comment:
required
Please do not post HTML code or bbcode unless you want it to show up as code in your post. (or if you are a blog spammer, in which case, you probably aren't reading this anyway).
Prove you are human by solving a math problem! I'm sorry, but due to an increase of blog spam, I've had to implement a CAPTCHA.
Problem:
0 plus 8
Answer:
required
2014-08-31

Cronos!

Not too long ago, I received a Minnowboard Max, the dualcore 1.3Ghz model, and it is a sweet bit of kit.

Hear is my quick review of the hardware.

Good

  1. A power button!
    Every time I shutdown an SBC like the Raspberry Pi or Beaglebone by pulling the power connector, I cringe and hope I don't mess up the file system. Thank you Minnowboard Max for the graceful shutdown.

  2. intel graphics
    A graphics chip with Open Source drivers maintained by the chip manufacturer? yes please!

  3. x86 processor
    Apparently this makes #2 possible. Well not really, but there don't seem to be any other SBCs that have an Open Source driver for the graphics chip that are not x86 based.

  4. SATA connector
    at some point, it would be great to add copious amounts of storage to this SBC

Bad

  1. No OS images are available with a kernel that has GPIO enabled. To be fair, this is not the boards fault. On a side note, I tried to compile the 3.16 kernel with GPIO and PWM support but I ended up borking something. No surprise there. /me is horrible at compiling kernels.

  2. UEFI in the firmware. bummer. This isn't as bad as it sounds either, although it is slightly more complicated than "install boot media and power up the device". Personally, I would love to skip UEFI and let the underlying BIOS handle all of my startup needs.

wow. how phenomenally indepth. :)

So what did I do with it? I'm glad you asked....

What I did with it

First, I tried to install Arch, but I couldn't get the /etc/fstab to properly recognize the /boot partition that had the UEFI boot jibberjabber on it. Can I blame this issue on UEFI? Does it have something to do with the UEFI requirement that the boot partition is formatted FAT32? Does that mean I can blame Microsoft as well? Does it matter that I was installing to the Micro SD card?

we may never know. Perhaps I was too hasty to give up, but I was itching to create, and not to debug.

Following the instructions at elinux.org, I installed Debian 8 (jessie) using the AMD64 netinstall image and then began installing the packages that I needed for compiling software and running scripts. A USB soundcard and an 802.11n wireless card were collected for the build. Then I put shit together.

Make A Case

For the most part, I recycled the case from the horrid Odroidx computer.

Suspend the board

zip ties, yarn, and small eye screws make great stand-offs.

Here is the USB card with small speakers connected to it. A sweet microphone was later added to the mix.

Bend some metal

METAL!!!!!
This is part of the sheet metal that was donated to me by the recipient of windchime #3. Thanks Buddy!

What you are looking at is a microphone holding bracket screwed to the wall.

Microphone check! one two one two

Oh my, is that a sweet rewired mic that I see there? yes, yes it is.

Did I mention that I reused a lot of projects in this project?

On the wall!

There she is: Cronos, right next to the "music room".

Recycling projects made this a bit of a breeze. The toughest part was wiring the electrical outlet behind the case so that I wouldn't have to expose any wires. keeping it clean. BOOYAH!

Software

A build is fine and dandy, but what is it running, and what does it do?

Chime the hour

Every hour, on the hour, cron runs a fairly simple Ruby script to play a "chime" for each hour of the hour. The cron code looks like

0 * * * * /usr/bin/ruby /opt/chime/chimer.rb

And the ruby script is:

#!/usr/bin/env ruby

#where is the chime?
this_dir File.expand_path(File.dirname(__FILE__))
chime File.join(this_dir'chime.ogg')
vol 1.0

hour Time.now.hour
if hour 22 or hour 7
  vol 0.1
elsif hour 21 or hour 8
  vol 0.4
end

#what command plays the audio?
play_cmd "gst-launch-1.0 playbin uri=file://#{chimevolume=#{vol&"
puts play_cmd

hour -=12 if hour 12
hour.times do |i|
  system(play_cmd)
  sleep 2
end

And the chime audio is a recording of low note from wind chime number 2 with the pitch shifted. Hey! Where is the video of windchime 2?

Text to speech

Thanks to the USB sound card, the computer has audio out other than through HDMI.

For converting Text to Speech, I am using festival with Arctic voices.

Aside from the system itself using festival for text to speech, I am also running a modified version of my ruby webrick based web server for text to speech that uses festival and allows me to send text to speech commands to the computer from any network connected device.

I should mention that although the Minnowboard Max is a fairly speedy little computer, festival text to speech is quite the resource consumer and there is a delay between when a request for speech happens and when the resulting audio is actually heard. This lead to a feature in Blather.

Damn it computer! Do what I tell you!

Blather handles all of the voice commands for telling devices on my network what to do.

Because I needed some sort of instant feedback for whether Blather accepted my voice command or not, an option was added for running a script when a valid voice command was detected. Similarly, an option was added for running a script when an invalid voice command was detected.

In this implementation, the "valid script" plays an "affirmative beep" and the 'invalid script" plays a "negative beep". Since no one offered to help me with the audio, I busted out my cheapo USB mic and recorded my own files. :) oh man....

Affirmative: bing!

Negative: booduhbooduh

Well there she is. Now if you will excuse me.... "Play Iron Maiden"

Comments
2014-09-05 Alison Chaiken:
Another amazing and inspiring post! I'd be happy to help you compile the kernel if you want to take another whack at it.
Name:
not required
Email:
not required (will not be displayed)
Website:
not required (will link your name to your site)
Comment:
required
Please do not post HTML code or bbcode unless you want it to show up as code in your post. (or if you are a blog spammer, in which case, you probably aren't reading this anyway).
Prove you are human by solving a math problem! I'm sorry, but due to an increase of blog spam, I've had to implement a CAPTCHA.
Problem:
5 minus 0
Answer:
required
2014-07-29

A few days ago, the Inspiration Wizard cast a spell upon me, and through arcane forces unknown, the designs for some shelves rushed through my mind. In a hasty blur, the design ideas were hastily transferred to paper before the ephemeral images vacated my conscience.

After acquiring an assortment of hardware, there was just one more important tool to purchase... a metric tape measure. Sweet! Now it's time to get to business.

step 0: gathering the supplies

Based upon the amazingly detailed schematic I created, it was fairly obvious what sort of material I would need.... haha just kidding.

I sort of moseyed about the local hardware store until I found the steel cable, cable locks, washers, and eye bolts that tickled my fancy. Then I bought a 6' 10"x1" piece of pine. pfffttttt "feet and inches"

Start at the top!

Two 125cm pieces of so called 2x4s where screwed to the workshop rafters as the anchor supports. Before attaching the supports, holes were drilled and eye bolts were attached. The eyebolts will anchor the shelf to the supports.

Add some cables

Some small goofy fraction measurement of cable was purchased in 5 foot lengths; it might have been 3/32 or 5/35ths or 1/8th. It was about 2 or 3mm.

A small loop was put through the eye anchor and then locked down. The bolt on the lock is about 7mm and I need to buy a 7mm open ended wrench to properly tighten these down.

Add a slab

The 6 foot piece of wood was cut in half width-wise and 4 holes were drilled in each half.

the hanging cables were placed through the holes, followed by a washer and a cable lock. A level was used to make sure everything was level. fancy that.

Repeat!

Go look at that hella sweet schematic again. It says "repeat", and that is what I did. :)

And there you have it, one sweet suspension shelf that is ready for me to put crap on.... and it is earthquake proof.

Now quit reading... and um... go read some Robert E. Howard

Comments
2014-07-29 Mikael:
That is a nice shelf! :)

As for myself think I could not have such a shelf, since I would dufferdly bumble into it and break things ;-)

Those white things in the roof, is that insulation? And what it is made of?

We have had the metric system for ages here in Sweden, but in carpentry it lived on for a very long time. Until maybe 10 years ago, I bought wood in "2inch4" etc dimensions, even in shops aimed at consumers. Funny enough, the length was in centimeters. I still think in those terms. Not that I build anything, as I have no house anymore.
2014-07-29 jezra:
Yes, the white stuff is the insulation in the roof of the workshop. The idea is to put either soft things or indestructible things on the shelf so that when I inevitably bump into it, nothing will break.
2014-07-29 Windigo:
Sweet shelves! An excellent way to prevent stubbing your toes on conventional floor-based shelving.
2014-07-29 jezra:
Damn it! Shelf 2 is floor based.
2014-07-29 Mikael:
I haven't seen that type of mounting/placeing/notsurewhattheenglishwordis of insulation here. Interesting. Not that I can say it doesn't exist here. I am not a professional builder.
Name:
not required
Email:
not required (will not be displayed)
Website:
not required (will link your name to your site)
Comment:
required
Please do not post HTML code or bbcode unless you want it to show up as code in your post. (or if you are a blog spammer, in which case, you probably aren't reading this anyway).
Prove you are human by solving a math problem! I'm sorry, but due to an increase of blog spam, I've had to implement a CAPTCHA.
Problem:
0 plus 9
Answer:
required
subscribe
 
2014
2013
2012
2011
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008