Automatic datavalidation in postgres

I have a system that continously logs various environmental parameters at home. Occasionally one of the sensors delivers some wrong readings and I would like to stop them from showing up in analyses and plots. To do this, I am inserting the data through a function that autmatically flags data that have too high or too low values – too high and low being defined for each physical sensor.

The part of the database that helps me achieve this is defined as
create table measure(
id serial primary key,
value float not null,
sensorid integer references sensor(id),
use boolean not null default true,
timestamp datetime default now()
)

When I am using data, I am reading them from the view measure_qa defined as
create view measure_qa as
select * from measure where use=true

Data about each physical sensor is stored in table sensor:

create table sensor(
id serial primary key,
typeid integer references type(id),
name varchar not null,
maxvalue float not null,
minvalue float not null
)

and for each sensor type in table type:

create table type(
id serial primary key,
name varchar,
unit varchar)

To insert data, I have defined the function addmeasurement as

CREATE FUNCTION addmeasure(double precision, integer) RETURNS integer
LANGUAGE plpgsql
AS $_$ declare
sval float:=$1;
sid integer:=$2;
mx float;
mn float;

begin
select minvalue,maxvalue into mn,mx from sensor where id=$2;
insert into measure(sensorid,value,use) values(sid,sval,mnsval);
return 0;
end;
$_$;

By calling addmeasure with the reading and the sensor id as parameters, it will check the allowed max and min values for the actual sensor and .set the use-field accordingly – if the value is within the allowed span, it is true, else it is false – and the value will not be used. It could also be possible to add in validation if the value has been fluctuating too much within a given timespan – I may implement that later on. In that case, I must consider how long time has gone since the last valid data point has been inserted and how much the data should be allowed to change per time unit.

I could also have made the use-field a varchar field (or as a foreign key to a lookup table) – then I could have had e.g. “OK” as default value and the value for data that should be used later on, and I could have made a difference between data points that were automatically discarded and data points that I have manually marked as invalid.

A important, but potentially difficult part is to set the max and min values right. They should trigger on as many error as possible without flagging valid data as invalid. It might be useful to know how the various sensors fails. E.g. I am using some ds18b20 temperature sensors. If they are not initiated properly, they may return either -127, +85 or 0 °C. I live in a place where the outdoor temperatures may go below freezing for several month of the years, so for an outdoor sensor, I cannot automatically filter out 0°C errors, so I set the limits to -50 / +60 which is far outside observed temperatures here but for the indoors sensors, (which never should go below 15 or above 45, I can set the limits to 2 and 40 °C.

Posted in Data | Comments Off on Automatic datavalidation in postgres

How to move a VboxManager virtual machine to another host

Officially, this has to be done using the clone function in vboxmanager – but you may (as I did) come up in a situation where the virtualbox system in the original host for some reason is not usable.

I moved my virtual machine between two 64-bits linux systems (the original host running ubuntu, the new host running debian). First I copied the entire directory containing the vm from the old host to the new one. Then I had to look at the .vbox file in that directory (the vm is called dbserver) which starts like this:

< ?xml version="1.0"?>
<!--
** DO NOT EDIT THIS FILE.
** If you make changes to this file while any VirtualBox related application
** is running, your changes will be overwritten later, without taking effect.
** Use VBoxManage or the VirtualBox Manager GUI to make changes.
-->
<VirtualBox xmlns="http://www.innotek.de/VirtualBox-settings" version="1.12-linux">
<Machine uuid="{29fc488f-7e02-4564-b407-373dd72731c3}" name="dbserver" OSType="Ubuntu_64" currentSnapshot="{bf8a6162-452f-4433-b0ac-20732c166748}" snapshotFolder="Snapshots" lastStateChange="2013-04-20T16:07:17Z">
<MediaRegistry>
...

The important part is the “Machine uuid” In the global settings file for vboxmanager, Virtualbox.xml, I had to add a line within the <MachineRegistry>


<MachineRegistry>
<MachineEntry uuid="{29fc488f-7e02-4564-b407-373dd72731c3}" src="/home/morten/VirtualBox VMs/dbserver/dbserver.vbox"/>

– then the vm could be started with the disks in the same state as it was on the old host.

There might be that I also should have added some information within <MediaRegistry>, but so far it seems to run just fine – and I can do a clone for backing up.

On the linux systems, the files for the vm are stored within ̃~/VirtualBox VMs/<vmname> – ie in my case ~/VirtualBox VMs/dbserver. The global settings file is ~/.VirtualBox/VirtualBox.xml – in other systems, it may be stored other places. – I have no idea if this will work to move a vm between two hosts with different OSs.

Posted in Data, linux | Comments Off on How to move a VboxManager virtual machine to another host

Sensor testing

After a DHT22 arrived a couple of days ago, I have had quite a few sensors running on my desktop:

  • DHT11 humidity and temperature sensor
  • DHT22 humidity and temperature sensor
  • BMP085 air pressure and temperature sensor
  • DS18B20 temperature sensor
All the sensors are situated close together.

DS18B20 in foreground. DHT11 (blue) at the back, DHT22 (white) in the middle and BMP085 (red PCB) at the right.

All the sensors are sampled at approximately 15 minutes intervals. The DHT11, DHT22 and BMP085 are all connected to the same controller and are sampled at the same cycle, The DS18B20 is connected to another system which may be sampling at other moments, although at the same frequency. (more information on the hard- and software for sampling can be found here)

Temperature
The DS18B20 is set up to 0.5 degree resolution. According to the documentation, this is consistent with the accuracy, although it may report values with a much higher resolution. The DHT11 is reporting temperatures with a 1 degree resolution the BMP085 and DHT22 both returns temperatures with a 0.1 °C resolultion. The temperatures from the last approx 36 hours seems to fit reasonably well.

The temperature curves fits reasonably well

Temperatures measured with different sensors

Relative humidity
When it comes to relative humidity, only the DHT22 and DHT11 can be compared. The DHT11 is reporting humitities with a 1% resolution and the DHT22 with a 0.1% resolution, so some differences are expected. But it turns out that the DHT11 seems to be a much poorer detector than the DHT22. It kind of gets the right humidity, but is really inaccurate.

The DHT11 shows a nearly straight line, varying between 35 and 36%, with a few jumps down to 34% at the start. The DHT22 shows a much larger span.

Relative humidity logged with a DHT11 and a DHT22.

Using just one detector of each kind, it is of cource difficult to give any general conclusions. By breathing on it, I can get the DHT11 to show a much higher relative humidity. It may be that one of my detectors is defective- but so far, it seems really to be worth it to shell out the extra to get a DHT22 rather than the DHT11.

Posted in arduino | Comments Off on Sensor testing

Fixing damaged pickguard

There should be some limits to stupidity – I tried to pick up my bass while the cable was plugged in and I was standing on the cable… It ended up with a broken pickguard:
The pickguard is broken, a piece has fallen out just above the jack

I don’t know how easy it is to find a new pickguard for an ’80 Ibanez so I decided to try to fix it. I needed something thin, strong and shapeable so I decided that a CD might fit the bill

IMGP0005_small

I drew the shape of the broken of piece of the pickguard on the CD and cut with a scissor along the line. To make things a bit easier for me, I centered the CD so that the jack fit through the centre hole.

IMGP0007_small

Having the template, I drilled a hole in the CD to be able to fit it temporary and find the shape for the rest of it.

IMGP0009_small

Then I could shape it

IMGP0010_small

and glue on the broken of part (note that I have leveled the upper end a bit of to make it fit a bit smoother.

IMGP0014_small

Then it was time to refit the jack

IMGP0017_small

and put it all togheter again.

IMGP0021_small

I don’t mind some “battle scars” on my bass, but this reminds me a bit too much of pure stupidity, so I may try to fix it up a bit more, maybe time to “borrow” some white nailpolish from some of the ladies in the house… (It can be seen that the pressure from the lowermost screw pushed it a bit out of shape)

IMGP0022_small

The old pickguard had a screening on the backside, that was of cource also broken. I have not (yet) noticed any increased noice, but I may take it a part and put on something later on (hah, famous last words). Either by gluing some tin foil to the back of the CD and the solder it to the old screening, or by refitting to screened cable from the jack.

Update – six months later: My fix turned out to be too unstable. I found out that it is no problem getting a new pickguard for fender basses, but not as easy for my ibanez, but I ended up ordering a new custom made one from Chandler music / pickguards.us – good quality and a perfect fit.

Posted in Diverse | Comments Off on Fixing damaged pickguard

Arduino and BMP085

The BMP085 is a barometric and temperature sensor. I’ve got one on a breakout board from geeetech. Using this and an arduino, it is possible to build an electronic barometer.

It can be connected to an arduino uno or nano:

BMP – Arduino
VCC – 3.3V
GND – GND
SCL – A5
SDA – A4

The sketch is originally written by Jim Lindblom at SparkFun Electronics, I updated it slightly to be able to use a more up to date wire library. BMP085.

This will report the temperature and barometric pressure (in Pascal) on the serial port. It is also possible to combine this with a DHT11 (or DHT21 / DHT22) sensor to also get a humidity reading. See https://github.com/sickel/DHT_BMP085. The DHT has to be connected to +5 and gnd, signal to port D2 on the arduino. The DHT library can be downloaded from arduino.cc.

Arduino nano, DHT11 temperature and humidity sensor,BMP085 temperature and pressure sensor.

Arduino nano, DHT11 temperature and humidity sensor (blue – at top),BMP085 temperature and pressure sensor (red – at bottom).

This work has been done in Arduino 1.0.1 on a debian system.

Posted in arduino | Comments Off on Arduino and BMP085

Reading temperature data out of postgres

I have set up a system logging temperatures (and later hopefully also other parameters) to a postgres database. The data are now read out and presented as an svg-graph. (this may not work in some older browsers, i.e. msie< 9 - it is possible to use svgweb, but I have presently not implemented this)

The temperature data may be presented as a svg graph.

Temperature graph. The number in the lower left corner is number of data points in the graph.

The source code for the system is available at my github account. The version presented here, is at tag passive_plot – in the last version it is possible to read out data, clicking in the chart. Later it will also be shown how to put more charts on one web page.

Why not just use cosm? Well, in fact I am uploading my data to cosm (in fact the intermediate json format used in this project is compatible with cosm), but on one side, I like to have control and know that I know where and in which format my data are, I also do not like the ways it is possible to present data on cosm (e.g. if a long time series is presented,points are thrown away, which may be strongly misleading if a point with a (local) minimum or maxima is removed – that happens quite often)

Posted in arduino | 2 Comments

Storing temperature data in postgresql

An arduino board is running as a web server serving temperatures read out from some DS18B20 sensors. The data are stored in a postgresql database. The data table has been defined as:

create table temps(
   id serial primary key,
   termid integer,
   temp double presicion not null,
   sensoraddr character varying(20),
   datetime  timestamp with time zone default now()
);

A php-script is set upp to poll the arduino and fetch data. It sends data as json, described here.

<?php
$server="192.168.0.177"; // Must be set up to match the arduino's IP.
$url="${server}/json";
$database='wdb';
$pgserver='localhost';   // postgres server
$username='.....'; // postgres user name
$password='.....'; // postgres password
$dbtype='pgsql';
try{
    $connectstring=$dbtype.':host='.$pgserver.';dbname='.$database;
    $dbh = new PDO($connectstring, $username, $password);
    if($dbtype=='pgsql'){
      $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }

  }
  catch(PDOException $e){
    $message=$e->getMessage(); 
    exit( "

Cannot connect - $message
");
  }

$fp = fsockopen($server, 80, $errno, $errstr, 30);
$data='';
if (!$fp) {
    echo "$errstr ($errno)
\n";
} else {
    $out = "GET /json HTTP/1.1\r\n";
    $out .= "Host: $server\r\n";
    $out .= "Connection: Close\r\n\r\n";
    fwrite($fp, $out);
    while (!feof($fp)) {
        $data .= fgets($fp, 128);
    }
    fclose($fp);
}
$data=split("\n",$data); // cuts of the headers
$jsondata=json_decode($data[3]);
$sql="insert into temps(temp,sensoraddr)values(?,?)";
$sh=$dbh->prepare($sql);
for($i=0;$itemp);$i++){
        $sh->execute(array($jsondata->temp[$i],$jsondata->address[$i]));
}
?>

This can be trigged from some event, or it may be run periodically. To make it run once every 15 minutes, save the php script as ‘fetchtemp.php’ and make the following shell-script in the same directory:

#!/bin/bash
while true; do
php fetchtemp.php
sleep 900
done

(or call it from cron or any other scheduler)

I have also a system for presenting the data as a svg-graph.

Posted in arduino, php, sql | 2 Comments

Arduino and infrared reflective sensor

Testing a infrared reflective sensor module.

I set it up with an arduino board, running the following sketch:

int sensorPin = 10;
int value = 0;
int prevval =0;
int count=0;
void setup() {
  pinMode(sensorPin,INPUT);
  Serial.begin(9600);
}
void loop() {
 value = digitalRead(sensorPin);
 if(value==0 && prevval==1){ // something is dected
   count++;
 }
 prevval=value;
 Serial.print(count);
 Serial.print("   ");
 Serial.println(value, DEC);
 delay(50);
}

To run this, connect dout on the sensor to digital pin 10 on the arduino, connect + on the sensor to 5V and – to ground.
When the infrared light is reflected back to the detector, the output goes low. The sensitivity can be adjusted using the trim pot, turning it counter-clockwise lowers the sensitivity, i.e. what passes in front must come closer or be more reflective. In addition to watching the serial monitor for changes, there is a led that lights up when something is detected.

To lower the sensitivity, turn ccw, turn cw to increase the sensitivity

Adjustments of the sensor

The sensor module is marked “auto-ctrl.com” and “LOGO-sensor Var1.5”.

Posted in arduino | Comments Off on Arduino and infrared reflective sensor

Store data from temperature server in couchdb

I am setting up a quick and dirty couchdb database to store data from an arduino temperature server running on http://192.168.0.177. (only visible on my local network)

All the code below is run under bash 4.2 on the debian system where the database resides.

The db is called arduino and is created by

curl -X PUT http://127.0.0.1:5984/arduino

Pulling out the data:

GET http://192.168.0.177/json

Storing it in the database:

curl -X POST http://localhost:5984/arduino -H 'Content-Type: application/json' -d <jsonstring>

This can be linked together:

GET http://192.168.0.177/json | curl -X POST http://localhost:5984/arduino -H Content-Type: application/json' -d @-

Note the last @- that makes curl read from standard input.

What we miss now is the timestamp. We can use sed to insert a timestamp in the json string:

sed -e "s/\"mil/\"time\":\"$dte\",\"mil/"

Will insert the string “time”: and the content of the variable $dte just before the “millis” in the json.

export dte=`date +"%F %T %z"`
GET 192.168.0.177/json | sed -e "s/\"mil/\"time\":\"$dte\",\"mil/" | curl -X POST http://localhost:5984/arduino -H 'Content-Type: application/json' -d @-

And to make it run each 2nd minute put it all into a file:

#!/bin/bash
while true; do
export dte=`date +"%F %T %z"`
GET 192.168.0.177/json | sed -e "s/\"mil/\"time\":\"$dte\",\"mil/" | curl -X POST http://localhost:5984/arduino -H 'Content-Type: application/json' -d @-
sleep 120
done

and run this with a nohup

To keep an eye on what goes in:

id=`tail -n1 nohup.out | awk -F'[,:\"]' '{ print $9 }'`;curl -X GET http://localhost:5984/arduino/$id

In the longer run, I am pretty sure these data should be stored in postgres – but for the first run testing, couchdb works fine. (Although, I could have rewritten the server to return sql-strings and run them through psql.)

Posted in arduino | 1 Comment

Arduino – temperature webserver

I am using an arduino uno, an ENC28J60 ethernet module and a few DS 18B20 temperature sensors. Presently, it seems to be possible to connect up to 7 sensors (although I have only tested with 3) by optimizing the code a bit for memory usage, it should be possible to add some more sensors. It should not be too hard to reuse much of this to use DHT11 or DHT22 sensors, but as far as I have understood, it is not possible to run more of those on one bus.

The temperatures may be read out in a browser or sent of as a json-string. The json-string also includes the sensors ids and a millisecond time stamp.
E.g.:{"temp":[23.00,23.50,-4.00],"address":["2852932640040","28A9D0264006D","2895D76E40050"],"millis":526288}

The web page is pretty simple

The web page as served from the arduino is pretty simple, Sensor 0 and 1 are measuring temperatures directly at my working desk, sensor 2 is just outside the window.

This is just a small part of what I hope will grow up to be a house monitoring system, adding on, among other things, devices for energy usage monitoring. I am planning to store the information in an sql database, but for the first stage testing, I am polling the server and storing the results in a couchdb.

The sketch can be found here:
Version 1.0 2nd feb 2013 or at github. It runs well on an arduino uno, but it is close to the limit of RAM usage. Just by adding a bit more text-output, the sketch will hang. If you want to add something, look through the sketch and see what can be removed (I have some serial debug logging and depending on the needs, it may be possible to remove either the part that serves html or the part that serves json.)

If using a newer ide than v 1.0, have a look at my description how to use the ENC 28J60.

Setup of the system

Two of the 18B20s can be seen. The gutted tp-cable runs to an outdoor one. (The Arduini Nano at the back end of the bread board is not in use in this project)

The data may also be forwarded to cosm (formerly known as Pachube). To get the data into the right format, make cosm call the cosm_uploader that further back talks to the arduino. (cosm_uploader at github).

The last five days outdoor temperatures at my place (More data can bee seen at feed 102668.)

Posted in arduino, Diverse | 2 Comments