xyzio

Setting up a golang website to autorun on Ubuntu using systemd

leave a comment »

Here is how to set up a website to auto-launch and restart on failure on Ubuntu using systemd. I’m using a simple site written in Go and compiled into an executable called gosite – I got sample Go code from Jeffrey Bolle’s page.

Simple golang website code

package main

import(
    "net/http"
    "log"
    "os"
)

const resp = `Simple Web App
Hello World!`

func handler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte(resp))
}

func main() {
    http.HandleFunc("/", handler)
    err := http.ListenAndServe(":8080", nil)

    if err != nil {
        log.Println(err)
        os.Exit(1)
    }
}

Setting up systemd

Once the code is ready and tested, lets move on to setting up systemd.

Create and open a file in the /lib/systemd/system folder:

 vim /lib/systemd/system/gosite.service

Edit the file with your parameters to match the contents below:

[Unit]
Description=A simple go website
ConditionPathExists=/home/user/bin/gosite

[Service]
Restart=always
RestartSec=3
ExecStart=/home/user/bin/gosite

[Install]
WantedBy=multi-user.target

Enable the service using systemctl:

root@hostname:/home/user# systemctl enable gosite.service
Created symlink from /etc/systemd/system/multi-user.target.wants/gosite.service to /lib/systemd/system/gosite.service.

Start the service:

service gosite start

Observe the service is running:

root@hostname:/home/user# ps aux | grep gosite
root 27413 0.0 0.2 827776 5012 ? Ssl 15:50 0:00 /home/user/bin/gosite

Written by M Kapoor

June 14, 2016 at 4:49 pm

Posted in Programming

Tagged with , , ,

Hacking Planet Atwood with Python and AWS

leave a comment »

Peter Atwood is a hobbyist who creates limited edition pocket tools and puts them up for sale on his site at Planet Pocket Tool.  His tools are fairly popular and being limited are hard to acquire.

Peter posts the sales randomly and the tools generally sell out within a few minutes of being listed.  The best way to capture a sale is to periodically check his site and get alerted when a sale is in progress.  This write-up is about automating the check and sending an alert via SMS and email using Python.

Blogspot publishes a RSS feed for their blogs.  I wrote a simple function to use feedparser to grab the datetime of the first item in the feed and compare it against the previous version.  I send out an alert if the datetime of the first item is different from the one I have saved.

#Get the blog entry
feed = feedparser.parse('http://atwoodknives.blogspot.com/feeds/posts/default')

#Figure out the publish time of the first entry
firstEntryPubTime = time.strftime('%Y%m%d%H%M%S', feed.entries[0].published_parsed)

#The newest post time did not match the previously saved post time
#We have a new post
if firstEntryPubTime != currentUpdateTime:

    #Save the new first blog entry time
    setCurrentUpdateTime(firstEntryPubTime)
    url = feed.entries[0].link
    subject = 'Atwood: ' + feed.entries[0].title
    body = url + feed.entries[0].summary

    #Send an alert
    send_alert(subject, body, url)

else:
    print "No Update"

Now, to send the alert we leverage Amazon Web Services and BOTO the AWS Python interface. Amazon has a service called Simple Notification Service or SNS. SNS is a push service that lets users push messages in various formats like SMS and email.

Getting started is simple. First create a topic to which people can subscribe using create_topic. Then subscribe your phone number, email address, and any other form of communication using subscribe. Now you are all set.

def send_alert(message_title, message_body, message_url):
    #Connect with boto using the AWS token and secret key
    c = boto.connect_sns('token','secret_key')
    topicarn = "arn:aws:sns:us-east-1:TopicName"
    #Publish or send out the URL of the blog post for quick clicking
    publication = c.publish(topicarn, url, subject=url[:110])
    #Close connection
    c.close()

I set up this script on a server at DigitalOcean and ran it periodically using cron. I was able to get to the buy link for most of Atwood’s sales with this methodology and eventually bought a Fancy Ti Atwrench. While nice and well made, it is definitely not worth what Peter Atwood charges for it.

Written by M Kapoor

June 10, 2015 at 11:58 pm

Recursively get all file names from a directory

leave a comment »

Recursively get all file names matching a substring from a directory.

Where:
* path = Directory to search
* matchStr = Substring to match

import os
import fnmatch

def getFiles(path, matchStr):
matches = []
for root, dirnames, filenames in os.walk(path):
    for filename in fnmatch.filter(filenames, matchStr):
        matches.append(os.path.join(root, filename))

return matches

Written by M Kapoor

April 12, 2015 at 2:21 pm

Posted in python

Project Nixie Tube Clock

leave a comment »

I become interested in Nixie tubes after I bought a Netduino and tried out the ArduiNIX.  From that I decided to make my own Nixie Tube clock.  My clock, besides showing the time, also shows the date, year, temperature, has an alarm, and can communicate with a PC via USART.

Hardware

The clock is built on two PCB boards connected by two 10 pin IDC cables.  I use stand-offs to screw the two boards together, doing that makes the clock free standing and eliminates the need to build a separate case or stand.  I would have done it on one giant board but that was not feasible due to size limitations in Eagle freeware.  The boards were manufactured through OSHPark.

I use four IN-17 Nixe tubes for the display.  Although they are small, IN-17 tubes are cheap and easy to source through Ebay.  Also I had several left over from my ArduiNIX experiment.

The tubes are multiplexed through 2 SN74141 BCD to decimal drivers.  I built a version with one driver per tube but that seemed wasteful which is why I decided to multiplex them.  I also tried a version where I drove the tubes with individual transistors but the switching was slow resulting in much ghosting.

The SN74141 drivers interface to the microcontroller through TLP-627 optoisolators.  I chose an optoisolator to isolate the microcontroller from the tube high voltage.  In theory it is cheaper to replace a $1.30 optoisolator than a $8 micro.  In my case the optoisolator did not isolate enough and I ended up ruining a MCU in a high voltage probing accident.

The microcontroller is an ATMega32.  It is run at 8MHz with the JTAG fuse bit disabled. I originally selected the ATMega32 because it has enough pins to drive four SN74141 tubes and perform serial I/O.  In hindsight, for the two drivers I ended up with, I could have gone to a lower pin-count MCU like the ATMega328 and saved some board space.  The code only uses 10% of the available 32KB of flash. It is nice to not have to worry about IOs or having to optimize the code to eke out every iota of performance and it leaves room for expansion.

The power-supply is based on the one in the ArduiNIX that I write about here.

The time, date, alarm, and temperature come from the DS3231 RTC chip on my RTC breakout board documented here.  I wired up a buzzer for the alarm but I didn’t read the datasheet correctly and wired one of its pins to the input voltage.  This leads to a high DC voltage across the buzzer which the datasheet warns again.  I’ve fixed this in the Eagle files so it will work when order another set of boards.

The user interface is through three push-buttons on the Nixie tube board.  One button is used to switch between the modes and the other two are used to increment the left and right sides.

In addition, I brought out the TX and RX pins for serial communication.  I used Dean Camera’s Interrupt Driven USART guide to get the interface up and running but I haven’t done much with it since.  It would be interesting to show stock prices and other numerical data from the internet on the display.  There are three LEDs available for debug, alarm, and to show seconds.

Software

The code is based around an overflow interrupt on Timer0.  The interrupt calls the RTC to get the current time.  From that the input pushbuttons, the alarm, and LEDs are toggled once per second.

The display() function drives the digits and uses a state machine to multiplex between them.  This avoids wasting cycles in a delay loop to implement a delay between switching displays to avoid ghosting.

UpdateLeftRight() updates the variables that hold the values to write to the tubes with the correct value based on the selected mode.  update_time() updates the time, date, day, and alarm based on the mode and which increment button the user is pushing.  The RTC data is read through the GetTimeDateAlarmDataFromRTC() function.

I didn’t wire the outputs of the SN74141 to the correct leads on the nixie tubes, Instead I wired them based on ease of routing.  remap() remaps the input to the driver to the correct value that should be written to the driver.

In addition, I have ‘anti_flashy‘ code to toggle the digits once per second through all their values per minute. This is done to avoid cathode poisoning that will eventually dim the tubes and also as a way to count the first 9 seconds of each minute.  It is a nice effect.   And since I don’t have the buzzer wired up, I toggle the debug LED on pin D6 when the time hour and minutes match the alarm.

Things I Learned

Be careful with the high voltage output.  I’ve shocked myself a few times by touching the board accidentally in a high voltage area.

Don’t probe around the board with wires hooked up to 170V.  I had a case where one of my tubes were not working and I tried powering them directly using very sloppy techniques.  Something shorted out and I ended up damaging the neighboring tube, shorting the optoisolator, and burning out the microcontroller!

Use IC sockets as much as possible.  Using a socket meant I could quickly replace a burnt out ATMega without having to rebuild a whole board.  Not using a socket for my tubes meant I had to re-do the entire display board when I fried one of the tubes.

Read the datasheets and then read them one more time.  Not reading the buzzer datasheet and just going off information from the internet meant that I wasn’t able to use the buzzer in my project.

Check your header directions and orientations of the components.  Print out a paper copy of your board, place your components on them, and check the pin orientation.  I put the tubes on the back of the board in one iteration of the design which meant that I had to re-do the board.

Always have a current limiting resistor in place.  Testing my tubes with high vcc and no limiting resistor resulted in them flickering and glowing when off.

Optimization

There is some optimization possible on the board and in the software.

For the hardware, I’ve added a switch to the board to turn off the clock at the input supply for when I’m away and of course fixed the buzzer.  There are enough I/O pins open to drive a LCD display to show additional information.  This with the serial I/O can give us a nice PC connected display.  The MCU is only running at 8MHz but can be clocked at up to 16MHz so there are plenty of spare cycles available.

The timings for reading the RTC and driving the display can be optimized further.  Initially I used delays to wait between turning off a tube and turning on its neighbor – you can see this in the commented out code in the display() function.  I later took out the delays but did not check to see if I can read the RTC or multiplex the tubes less often.  This will save power and free up cycles for additional features and effects.

Additional effects are possible with the tubes.  Things like flickering, scrolling, fading in, fading out e.t.c

Special Thanks

For the original inspiration and for sharing their designs:
http://arduinix.com/

Adafruit and Sparkfun for their articles and sharing their Eagle libraries.

For inspiration and samples of code for driving the DS3231 RTC chip:
http://www.elektronika.ba/800/warm-tube-clock-v2-nixie-clock/

Links

All code and files are released as ‘Do what you want with it. I am not responsible for anything that happens.’

My source code:
https://bitbucket.org/xyzio/avr-code/src/master/two_driver_board/two_driver_board/

CPU board schematic:
https://bitbucket.org/xyzio/circuits/src/master/Two%20Driver%20CPU/

Tube board schematic:
https://bitbucket.org/xyzio/circuits/src/master/Two%20Driver%20Tube%20Board/

Pictures

Front of Nixie Tube Clock

Front

Back of Nixie Tube Clock

Back

Top view of Nixie Tube Clock

Top view

 

Video Demo

Written by M Kapoor

April 6, 2015 at 1:46 am

Driving Adafruit’s RGB Matrix with Python on the BeagleBone Black

leave a comment »

I wrote this code to drive the Adafruit 32×64 RGB Matrix using a Beaglebone Black and Adafruit’s IO Python library.  The code is super simple – it writes a static color background to the top and bottom halves of the display through the shift registers and triggers the latch.  It then iterates through the addresses so the LEDs for that row turn on and then goes to the next address.  This should create a background color through persistence of vision.

Along the way I discovered:

The Python Library isn’t fast enough to drive the RGB matrix to provide a persistent display.  There is flicker and when updating colors, you see each row turn on and off.  You literally see the delay.  There are ways to speed up the writes by using the PRU or direct IO writes.  But I should not have to do that on a 1GHz processor.

The RGB matrix doesn’t light up unless you continually change the address.  This was really annoying when I was figuring things out.  I did not find this documented anywhere on the web except on rayslogic’s RGB writeup.

It appears the BeagleBone Black’s IO pins cannot push enough current to turn on the input schmitt triggers.  I spent a lot of time being frustrated because I couldn’t get the green and blue LEDs to light up on my board.
Finally I noticed the green LEDs were barely on and had a brightness gradient from low to high address.  My guess is the address pin was barely turning on which meant 0 was the most common address – hence the higher brightness on the lower rows.  I got around this by plugging the G(reen) input directly into the 5V pin on the BeagleBone Black.  Of course this now meant the green LEDs are always on!

Adafruit charges too much for the RGB panels.  For example, the seller kbellenterprises on ebay has a 16×32 RGB matrix for $16 including shipping.  Adafruit has the same panel for $25 and you pay for shipping.

Adafruit charges too much for male-to-male jumper wires.  The seller funny-diy on ebay sells 40 for $1.80 with shipping while Adafruit charges $4+shipping for their so-called “premium” wires.  Adafruit needs to rename them to “premium-priced“.

My Python Code:
https://bitbucket.org/xyzio/rgbmatrix/src/master/bb_python/logic.py

Sources:
http://www.rayslogic.com/propeller/programming/AdafruitRGB/AdafruitRGB.htm
https://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black/overview

 

Written by M Kapoor

April 3, 2015 at 4:12 pm

Installing Debian on the Beaglebone Black Rev B

leave a comment »

I wanted to flash my BeagleBone Black Rev B to Debian so I could try installing a wi-fi dongle.  The Rev C is the latest version of the BeagleBone Black and I couldn’t find out if the Debian on the BeagleBone website supported the Rev B.  I decided to just try it out.

So for those that are wondering, yes Debian version 2014-05-14 works on the BeagleBone Black Rev C.  The instructions on their getting started page work.

And once you have Debian, the WiFi dongle setup instructions here on Adafruit (pdf) will work to set up your dongle.

Installing Debian on BeagleBone Black Rev B

Written by M Kapoor

January 5, 2015 at 1:16 am

Nmap: Searching for open port 22 over a range of IPs

leave a comment »

nmap -sV -p 22 198.168.1-12.1-127

Written by M Kapoor

January 4, 2015 at 1:37 pm

Posted in nmap

Non-Arduino Adafruit OLED Display Library

leave a comment »

Adafruit sells a really nice 16×2 OLED display and they even have an Arduino library for it.  However I only have a Atmega32 and Arduino does not run on the Atmega32.  Rather than spending $20 or so for an Arduino, I decided to port their library to AVR.  It wasn’t too difficult since Arduino is just AVR C++ behind the scenes.

Re-writing the Adafruit library was straightforward.  I hardcoded PORTA as the I/O port but some additional code could make that generic.  I had to re-write the digitalRead and digitalWrite functions to read and write out of PORTA instead of the Arduino pins.  The delayMicroseconds command is replaced by the AVR _delay_ms() macro.

The trickiest part was figuring out how to implement the print function.  After some digging around I found it in the Arduino code at \hardware\arduino\cores\arduino\Print.cpp.  The print function calls a write function that iterates through the character string which then calls our native OLED write on each character.  This seems seems a little roundabout but I guess that is how they chose to implement it.

Adafruit 16x2 OLDED display

Links:

My No-Arduino code:
https://bitbucket.org/xyzio/avr-code/src/master/characterOLED/

Adafruit Arduino library:
https://github.com/ladyada/Adafruit_CharacterOLED

Youtube demo:

Written by M Kapoor

December 26, 2014 at 3:02 pm

How to use a different version of Python in PyCharm

leave a comment »

How to use a different version of Python in PyCharm.

File -> Settings (Ctrl + Alt + S)

Click on Project Interpreter. Select your desired version of Python.

Written by M Kapoor

October 2, 2014 at 4:58 pm

Posted in python

Validating a XML against XSD schema in C#

leave a comment »

Inputs:

xmlFileName: Input XML file name
schemaFileName: Input XSD file name

Output:

results: Results output

using System.Xml;
using System.Xml.Schema;
using System.IO;

static List<string> results = new List<string>();

        static void Validate(string xmlFileName, string schemaFileName)
        {
            XmlDocument x = new XmlDocument();
            string source = xmlFileName;
            x.Load(source);

            XmlReaderSettings settings = new XmlReaderSettings();
            settings.CloseInput = true;
            settings.ValidationEventHandler += Handler;

            settings.ValidationType = ValidationType.Schema;
            settings.Schemas.Add(null, schemaFileName);
            settings.ValidationFlags =
                 XmlSchemaValidationFlags.ReportValidationWarnings |
            XmlSchemaValidationFlags.ProcessIdentityConstraints |
            XmlSchemaValidationFlags.ProcessInlineSchema |
            XmlSchemaValidationFlags.ProcessSchemaLocation;

            StringReader r;
            using (StreamReader sr = new StreamReader(source))
            {
                r = new StringReader(sr.ReadToEnd());
            }

            using (XmlReader validatingReader = XmlReader.Create(r, settings))
            {
                while (validatingReader.Read()) { /* just loop through document */ }
            }
        }

        private static void Handler(object sender, ValidationEventArgs e)
        {
            if (e.Severity == XmlSeverityType.Error || e.Severity == XmlSeverityType.Warning)
                results.Add(String.Format("Line: {0}, Position: {1} "{2}"", e.Exception.LineNumber, e.Exception.LinePosition, e.Exception.Message));
        }

Written by M Kapoor

September 30, 2014 at 3:21 pm

Posted in c#