Skip to content

The server running on power.studentergaarden.dk to log power usage and show a nice graph.

License

Notifications You must be signed in to change notification settings

Studentergaarden/blipserver

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

blipserver

About

This is the code running on power.studentergaarden.dk (only accessible from internal net) and is based on power.labitat.dk

It reads data from the Arduino connected to the serial port, which monitors the power meter, and serves the power graph and an API for retrieving past power meter data.

Each time the Arduino detects a new blink of the power meter it sends the amount of milliseconds passed since last blink as a decimal string followed by a newline ("\n").

Upon receiving such a value from the Arduino the server attaches a timestamp (unix timestamp in milliseconds) and stores this pair in a database. It also returns the point to any clients doing long-polling to update the live graph.

The server is written in lua using the Lua Event Machine, along with the stream and PostgreSQL libraries for it.

API

The database stores pairs (stamp, ms) for each blink of the power meter. Here stamp is a unix timestamp in milliseconds describing roughly when the blink happened, and ms is the number of milliseconds which passed since the last blink detected. We’ll refer to such a pair as a “point”.

The power meter blinks once for each Wh of power used (600 times for each kWh). Use the formula

3600*600 / ms

to calculate the (mean) power usage in Watts during the time interval [stamp - ms, stamp].

The points can be fetched by doing HTTP requests to various URIs. JSON is the only output format supported and points will be returned in a JSON array [stamp, ms].

Clients should not assume that stamp1 + ms2 = stamp2 for every two consecutive points (stamp1, ms1) and (stamp2, ms2). There may be time drifts, rounding errors or both. Also the blip server may have been down for some period of time due to maintanence or other hacking and thus not been able to log some blinks.

  • /blip/id:: :Use this URI to do long-polling. The server will not answer the request :immediately, but instead wait until the next blink is detected and :then return that point.
  • /last/id:: Immediately returns the last point read.
  • /last/id/<n>:: Returns a list points read during the last `<n>` milliseconds.

    If there are more than 20000 such points only the first 20000 will be returned.

  • /since/id/<n>::

    Returns a list of points since `<n>`, which must be a unix timestamp in milliseconds.

    If there are more than 2000 such points only the first 2000 will be returned, so use 1 plus the timestamp of the last point in the list to request the next 2000 points (again using this URI).

  • /aggregate/id/<n>/<m>/<c>::

    Returns aggreated usage over a time period. The period starts at `<n>`, which must be a unix timestamp in milliseconds.

    The aggregation interval is `<m>`, in milliseconds. Eg. 3600000 to get usage per hour. The number of points returned is `<c>`.

  • /hourly/id/<m>/<n>::

    Returns usage per hour. The usage is returned in the interval `<m>` to `<n>`, in unix millisecond timestamps. 5 values are returned for each hour-interval:

    • The unix millisecond timestamp of the start of the hour-interval
    • The number of blips received during that hour-interval
    • The average usage during that hour, in watts.
    • The minimum blip length in that interval, in milliseconds.
    • The maximum blip length in that interval, in milliseconds.

Create database

Install postgresSQL

$ sudo apt-get install postgresql

Log into the database as postgres user and create the user powermeter

$ sudo -u postgres psql
=# CREATE USER powermeter CREATEDB;

exit by C-d and create powermeter database with the relevant tables

$ createdb -U powermeter powermeter 
$ psql -U powermeter -f /path/to/schema.sql

And you’re done!

Get the database size

$ sudo -u postgres psql -U powermeter -c "\d+"

or as root

$ psql -U powermeter -c "\d+"

If you have problems connecting to the database, try changing peer to trust in the following file

$ sudo nano /etc/postgresql/9.1/main/pg_hba.conf
local   all             all                                     peer

Connect to the server

blip.lua is set to listen to port 8080 as standard, eg. http://localhost:8080 should give you a nice graph.

Create alias for /dev/ttyUSB0

In order to give a persistent name to a specific Arduino device, we need a rule to udev. First find serial number for the Arduino (without grep a lot of info about the usb is shown): $ udevadm info -a -n /dev/ttyUSB* | grep '{serial}' | head -n1

Then add the rule

$ sudo nano /etc/udev/rules.d/99-usb-serial.rules
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A9007Q1P", SYMLINK+="arduino"

and update udev

$ sudo udevadm trigger --action=change

src{SYMLINK+=”arduino”} means that UDEV should create a symlink /dev/arduino pointing to the actual /dev/ttyUSB* device. In other words the device names will continue to be assigned ad-hoc but the symbolic links will always point to the right device node.

Make apache listen to port 8080

It is not possible to POST information cross domain, subdomain, or port number, in this case port 80 and 8080.

One way to circumvent this is to set up a very simple reverse proxy (using mod_proxy if you are on Apache). This will allows to use relative paths in the AJAX request, while the HTTP server will be acting as a proxy to any “remote” location.

The fundamental configuration directive to set up a reverse proxy in mod_proxy is the ProxyPass. It will typically be used as:

ProxyPass /ajax/ http://www.localhost:8080/

In this case one would request /ajax/blip with jQuery, but in fact the server would serve this by acting as a proxy to http://www.localhost:8080/blip internally.

The proxy module needs to be activated in apache

# a2enmod proxy_http

Then write the site-file as

# emacs /etc/apache2/sites-available/power.studentergaarden.dk
<VirtualHost power.studentergaarden.dk:80>
	#
	# Public information
	# ------------------
    ServerName power
	# ServerAlias rating
	ServerAdmin [email protected]

    ## IMPORTANT!
    ProxyPreserveHost On
    ProxyRequests Off
    ## The following line is actually the only needed line!
    ProxyPass /ajax/ http://localhost:8080/
    ProxyPassReverse /ajax/ http://localhost:8080/
    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>
    ## TO HERE!

	#
	# Logging
	# -------
	ErrorLog /var/log/apache2/power.studentergaarden.dk_error.log
	CustomLog /var/log/apache2/power.studentergaarden.dk_access.log combined
	CookieLog /var/log/apache2/power.studentergaarden.dk_cookie.log

	#
	# Rewrite rules
	# -------------
	RewriteEngine On
	RewriteCond %{HTTP_HOST} !power\.studentergaarden\.dk
	RewriteRule ^(.*)$ http://power.studentergaarden.dk$1 [R=301]

	#
	# Main site
	# ---------
	DocumentRoot /share/sites/power.studentergaarden.dk/DocumentRoot
	<Location />
		Order deny,allow
		Deny from all
		Allow from 172.16.0.0/16
		Allow from 130.226.169.160/27
	</Location>
</VirtualHost>

Running the server

Start the server from a SSH connection and redirecting output to dev/null in order to avoid writing output from the server to the nohub.out file

# nohub "./blip.lua" > /dev/null 2>&1 &

Maybe setup a init script: https://www.debian-administration.org/articles/28

Example

power-washing-machine.png

The ripples (around 100W) in this picture comes from a washing machine. The spike at 17:44 is either the compressor in a freezer or a fridge starting up. The 2kW power draw every 13-15 minutes is the coffeemaker that keeps water hot.

License

blipserver is free software. It is distributed under the terms of the GNU General Public License

About

The server running on power.studentergaarden.dk to log power usage and show a nice graph.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 64.7%
  • HTML 32.2%
  • Lua 1.6%
  • PHP 1.1%
  • CSS 0.3%
  • Shell 0.1%