Andreas @ MadFlex
Apr 18, 2012

Pymacs -- usage example

For a recurring task I wanted to read a key in the minibuffer of Emacs and insert data from a xml file using xpath.

The simplified version of my solution using pymacs:

from Pymacs import lisp
from lxml import etree

interactions = {}

def insert():

  filename='data.xml'
  doc = etree.parse(filename)
  templates = doc.xpath('//tours/templates/template/@name')

  # list of templates to insert with numbers from 0 to n
  tlist = ["[%d] %s" % (i, templates[i]) for i in range(len(templates))]

  # show the list of templates to choose
  lisp.message("Which template (%s)?" % tlist)
  # read character
  key = lisp.read_char()
  # check if key is a number
  if key >= ord('0') and key <= ord('%d' % len(templates)):
    tempnum = key - ord('0')

    # save current curser position
    start = lisp.point()
    # insert string
    lisp.insert("%s\n" %
                etree.tostring(doc.xpath("//tours/templates/template[@name='%s']" %
                                         templates[tempnum])[0], pretty_print=True,
                                         encoding=unicode))
    # goto saved position
    lisp.goto_char(start)

interactions[insert] = ''
# set f6 for this function (mypymacsmodule is the name of this .py file)
lisp.global_set_key((lisp.f6,), lisp.mypymacsmodule_insert)

The version I use has to modify the data from the xml file using a jinja based template.

Jan 17, 2012

Writing a Postgresql connector in FlaskSQLAlchemy

We want to use the postgresql database for authentification of our web application. The username and password is stored clientside in a SecureCookie (see flask.session). This cookie has to be read before every request and the database connection has to be established:

from flask import request_started, session
request_started.connect(connect_db, app)

def connect_db(app, data=session):
    if 'u' in data and 'p' in data:
        app.config['SQLALCHEMY_DATABASE_URI'] = \
            app.config.get('DATABASE') % (data.get('u'), data.get('p'))
        db.init_app(app)

A few problems arise with this scenario:

1) The database connector in FlaskSQLAlchemy has to be reset, because reading the connector of another user is not wanted.

subclassing of SQLAlchemy this way solves this issue:

from flaskext.sqlalchemy import SQLAlchemy, get_state

class MySQLAlchemy(SQLAlchemy):
    """ subclass of Flask-SQLAlchemy, because we need to clean the
    connector on every request. Improvement: save connector for every
    user session?!
    """

    def get_engine(self, app, bind=None):
        """Returns a specific engine.
        changed for using a new connector on EVERY request.
        """
        with self._engine_lock:
            connector = self.make_connector(app, bind)
            state = get_state(app)
            state.connectors[bind] = connector
            return connector.get_engine()

2) Armin added an AssertionError if the request was already handled (see commit 5500986971b28f270a27db633acf19984eee609e). In our case the request is handled more than one time on every request. Because of this problem we use version 0.7.3 of Flask and not 0.8 at the moment.

This assertion is totally reasonable, but there should be an option to disable it!

One possible solution may be this branch: first-request-decorator on github/mfa.

Nov 20, 2011

Create Plots using rrdtool

Next step for my humidity logger is to get nice plots. Here rrdtool seems to be the tool of choice.

First create a few rrd-files. For example:

rrdtool create humidity.rrd --step 30 \
  DS:humidity:GAUGE:120:0:100 \
  RRA:AVERAGE:0.5:1:1200 \
  RRA:MIN:0.5:12:2400 \
  RRA:MAX:0.5:12:2400 \
  RRA:AVERAGE:0.5:12:2400

With update every 30 seconds, a GAUGE value from 0 to 100. Additional calculating average, minimum and maximum of the humidity value.

Adding new values for the plot in python using python-rrdtool.

def log_to_rrd(data):
  values = json.loads(data)
  dt = time.mktime(datetime.datetime.now().timetuple())

  ret = rrdtool.update('humidity.rrd','%d:%f' %
                       (dt, values.get('humidity')))
  if ret:
      print rrdtool.error()

And build a plot for one day:

def graph():
    ret = rrdtool.graph( fn, "--start", "-1d",
                         "--lower-limit=0",
                         "--title=Humidity",
                         "--vertical-label=-" + str(cnt) + str(size),
                         "DEF:hum=humidity.rrd:humidity:AVERAGE",
                         "LINE1:hum#0000FF:Humidity\\r",
                         "COMMENT:\\n",
                         "GPRINT:hum:AVERAGE:Avg Humidity\: %2.2lf%S%%",
                         "COMMENT:    ",
                         "GPRINT:hum:MAX:Max Humidity\: %2.2lf%S%%\\r")

Final example (with humidity, temperature and calculated dew point):

rrdtool example
Nov 07, 2011

Humidity Logger Version 0.1

Full code of the first running version of the humidity logger

(read more)

Nov 06, 2011

Saving Date and Time using a DS1307

The arduino has no time information. First I wanted to use NTP, but one HTTP client (the one sending the sensor data to the server) is enough difficulty for this problem. A friend of mine build a board similar to this setup: http://www.ladyada.net/learn/breakoutplus/ds1307rtc.html .

For initializing and reading the date/time information I use the code from http://www.glacialwanderer.com/hobbyrobotics/?p=12 .

Now I have date/time information for writing the sensor data to the SD card in the future.

Nov 06, 2011

Reading sensor data from a SHT1X

For reading the temperature and humidity a SHT11 is used. Using https://github.com/practicalarduino/SHT1x reading data from the sensor is amazingly simple. The example code in the repository is all I needed.

Nov 05, 2011

Receiving HTTP

The server side of my data logger is a very simple Flask site.

First version of the code:

from flask import Flask, request, abort
app = Flask(__name__)

import datetime

@app.route('/')
def index():
    return "nothing to see here ..."

@app.route('/input/', methods=['POST', 'GET'])
def input():
    if request.headers.get('X-ApiKey') != 'SECRET_API_KEY_SET_ON_ARDUINO':
        abort(403)
    if request.method == 'POST':
        log_to_file(request.data)
    return "OK"

def log_to_file(data):
    f = open('/tmp/arduino.logger', 'a')
    f.write(str(datetime.datetime.now()))
    f.write(': ')
    f.write(data)
    f.write("\n")
    f.close()
Nov 03, 2011

Arduino pushing data via HTTP

Client for HTTP POST on an Arduino.

(read more)

Oct 24, 2011

Arduino first steps

I want to know, why I didn't tried the Arduino before? Arduino is such a simple way into building something useful with a microcontroller.

First I wanted to use my new Arduino Uno only using console and Emacs. I used this stuff to get started:

The first program I tried was really simple (blinking LED on pin 9): http://arduino.cc/en/Tutorial/Blink

Using this Makefile (the Makefile.master is in the folder above):

# Your Arduino environment.
ARD_REV = 22
ARD_HOME = /opt/arduino-0022
AVR_HOME = /usr/bin
ARD_BIN = /usr/bin
AVRDUDE = /usr/bin/avrdude
AVRDUDE_CONF = /etc/avrdude.conf

# Board settings.
BOARD = uno
PORT = /dev/ttyACM0
PROGRAMMER = arduino

# Where to find header files and libraries.
INC_DIRS = ./inc
LIB_DIRS = $(addprefix $(ARD_HOME)/libraries/, $(LIBS))

include ../Makefile.master

After this only connect the arduino via USB and add one LED with an resistor to pin 13 and GND. Compiling and flashing using: make upload.

Amazingly simple!

Mar 31, 2011

Dante spring conference 2011

My personal notes from Dante spring conference in Bremen.

  • improved makeindex: Xindy
  • texdoc <FONT> helps including new fonts. i.e. texdoc bera
  • one complete font (with maths) is kpfonts
  • \showfont shows font used at the moment
  • use blindtext to get "lorem ipsum". But "Blindtext" is not Latin.
  • mathastext sets all text in formulars as text. To get variables in italic add [italic] at package loading time.
  • good Font catalogue: www.tug.dk/FontCatalogue.
  • try biblatex; don't use bibtex anymore.
  • with the option --wolfgang the capacity of bibtex8 will be increased to very huge
  • universal document converter: pandoc
  • new list typ for TeX: coollist; for strings coolstr and cool for maths
  • chronology to set time scales
  • with cntdwn a counter and a clock can be embeded in PDFs (using only with pdflatex or Acroreader)