Neuer Gammamonitor

Wir haben einen neuen Gammamonitor!
Seit dem 30.06.14 16:00 befindet sich der neue Gammamonitor an seinem Bestimmungsort.

Unser Messaufbau besteht aus:
1. Gammascout online, Nr. 45095, kalibriert mit +/- 5% (Zertifikat-45095), eingestellt auf minütliche Speicherung der Messdaten
2. „Raspberry PI“-Minicomputer mit entsprechender Software zum Auslesen des Gammascout und zur grafischen Aufbereitung der Messdaten
3. Kabelage

Zu den neuen Messwerten geht es hier-> Gammamonitor.

Jetzt wir es technisch…
Also, wenn Sie jetzt an dieser Stelle nicht weiterlesen möchten, ist das gut zu verstehen, aber vielleicht möchte der/die Eine oder Andere sich genauer informieren, hat Anregungen oder möchte das Ganze vielleicht auch nachbauen.
Das Projekt wird die nächsten Tage/Wochen noch vervollständigt und der Quelltext der Scripte noch verbessert. Wenn es Fragen und oder Anregungen dazu gibt, gerne melden!
Die Änderungen werden zeitnah an dieser Stelle dokumentiert.

Benötigte Komponenten:

Gammascout online
Wichtig: Es muss sich um das Modell ‚Online‘ handeln, da nur bei diesem die USB-Schnittstelle über das Kabel mit Strom versorgt wird; bei den anderen Modellen ist die Batterie bei derart häufigem Auslesen, wie wir es vorhaben, schnell am Ende.

USB-Verbindungskabel zwischen Gamascout online und Raspberry-Pi; wir haben für unsere speziellen Bedürfnisse, da der Gammascout entfernt vom Rechner betrieben werden soll, einen entsprechenden USB-Extender verbaut, bei dem das USB-Signal und die Versorgungsspannung über ein flaches Netzwerkkabel geleitet wird und somit genügend langes Kabel vorhanden ist.
Bezugsquelle: Elektronikhandel in der Nähe.

Raspberry Pi 2, 512MB-Version,
16GB SDHC-Karte(Class10), darauf wurde das aktuelle Debian-Linux für den Pi installiert,
Gehäuse für den Pi, Netzteil, Wlan-USB-Stick.
Wichtig: Auf die Chips müssen bei unserem Aufbau Kühlkörper geklebt werden (nicht vergessen: ebenfalls auf den Spannungsregler, da dieser im Betrieb sehr heiss wird); gerade im Dauerbetrieb überlebt der Pi sonst nicht lange.

Jetzt zur Software:
‚Das Rad neu erfinden‘
Da es im Netz bereits Anleitungen und Software für den Anschluss eines Gammascout an einen Pi gab, brauchten wir hier das Rad nicht komplett neu zu erfinden.
Die erste Anleitung fanden wir bei
http://www.messtechnik-manufaktur.de/radioaktivity/messaufbau/,
die wir entsprechend an unsere Bedürfnisse angepasst haben (ok, wir haben massiv geändert und ergänzt, die db läuft lokal auf dem Pi, im Script findet gleich auch die graphische Auswertung und der Upload der Dateien statt), der Ursprungscode ist teilweise noch erkennbar, also vielen Dank an o.g. Adresse!
Und wir benötigen natürlich auch die Schnittstellensoftware von hier:
http://johannes-bauer.com/linux/gammascout/?menuid=3

Benötigt wird als Erstes das Debian-Linux für den Raspberry Pi,
danach installieren wir auf dem Pi noch folgende Pakete:
1. Das Modul pyserial (pyserial.sourceforge.net),
2. die Datenbank mysql (über den Paketmanager installieren oder über apt-get install),
3. das Modul mysqlldb für die Datenbankverbindung mysql-python,
4. einen ftp-server auf dem pi,
5. ein vpn für den pi,
6. eine Fernsteuerungssoftware für den Pi. Der Pi kann dann bsp. über ultravnc über das virtuelle private netzwerk (vpn) ferngesteuert werden, ohne jedesmal vor Ort sein zu müssen (ich gebe zu, ich bin bekennender Mausschubser, deshalb die Fernsteuerung über VNC; eine Terminalverbindung täte es auch…)

Nachdem die Module alle installiert sind, können wir anfangen:
als erstes muss eine neue SQL Datenbank angelegt werden.
Die Tabellenstruktur der Tabelle für die Messwerte ist wie folgt aufgebaut:

 id          bigint(20)     NO    auto_increment
 datum       datetime       NO
 cpm         double         NO
 cps         double         NO
 dosis       double         NO

Danach erstellen wir ein Verzeichnis /Gammascout  der Benutzer hier: PI erhält volle Schreibrechte auf das Verzeichnis und seinen Inhalt.
Der FTP-Benutzer PI erhält ebenfalls Vollzugriff auf das Verzeichnis.

Folgende Dateien wird das Verzeichnis enthalten:

log.csv – wird bei jedem Auslesen des Geigerzählers erstellt; hier landen die aktuellen Messdaten
biglog.csv – enthält alle bisher aufgelaufenen Messdaten als kommagetrennte Werte und wird täglich gepackt und zur Verfügung gestellt
lastlog.csv – enthält jeweils den letzten ausgelesenen Wert, ab dem der DB weitere Daten hinzugefügt werden (spart eine doch etwas zeitaufwendigere Datenbankabfrage…)

24h.png
gestern.png
31d.png
– die erstellten Grafiken (weitere folgen)

bissgammascript (attribute: lesen, ausführen!)
– das Script, das regelmäßig ausgeführt wird

Unser erster Versuch, das script per cronjob laufen zu lassen, schlug fehl, die Daten wurden zwar ausgelesen, aber python weigerte sich die Graphiken zu erstellen, und die Fehlersuche brachte auf die Schnelle nichts (wäre bestimmt gegangen, aber ein anderer Weg war schneller).
Also ein anderer Weg:
Der Benutzer pi meldet sich automatisch an und im Autostart (/home/pi/.config/autostart/)
steht folgende Datei:
gammascout.desktop
Inhalt:

[Desktop Entry]
 Encoding=UTF-8
 Version=1.0
 Type=Application
 Exec=bash /home/pi/gammacronjob
 Terminal=true
 Name=gammascout
 Categories=Application;Development;

Im Homeverzeichnis des Benutzers pi steht folgende Datei:
gammacronjob (attribut ausführbar)
Inhalt:

 sleep 10
 SERVICE='uxterm'
 if ps ax | grep -v grep | grep $SERVICE > /dev/null
 then
    exit 0
 else
    uxterm &
 fi
 while true; do
    cd /Gammascout
    ./bissgammascript
    sleep 300
 done

Und jetzt zu unserem Python-Script:
bissgammasript (attribute ausführbar)
Inhalt:

 #!/usr/bin/python

import os
import MySQLdb
import csv
import datetime
import struct
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pylab as p
import ftplib
from time import sleep

def cpm2uSv(cps):
## An dieser Stelle erfolgt die Umrechnung der Counts per Second in Dosisleistungswerte
    return cps / 3.21
    ## Wert gilt nur fuer GammaScout NR.045095

# jahresmittelwert in meine
mwmeine = 0.08

# grenzwert in gorleben
gwgorleben = mwmeine + (0.3/8.76)

# grenzwert strvvo
gwallgemein = mwmeine + (1/8.76) 

# massstab y-achse (fuehrt sonst zu verwirrung...)
maxy = 0.3

## lastlog lesen
lastlog = open('/Gammascout/lastlog.csv', "rb")
read = csv.reader(lastlog)
for row in read:
    ## print row,
    lastdatetime = row[1]
lastlog.close()

from datetime import datetime
tobjlastdatetime = datetime.strptime(lastdatetime, "%Y-%m-%d %H:%M:%S")

lastdaysync = 0
if tobjlastdatetime.strftime("%j") <> datetime.today().strftime("%j"):
    lastdaysync = 1

os.system("/usr/local/GammaScoutUtil-0.04/gammascoututil -d /dev/ttyUSB0 readlog:csv:/Gammascout/log.csv")

## Oeffnen der neuen Logdatei ; Datenuebertragung zu sql, append an biglog

biglog = open('/Gammascout/biglog.csv', "a")
newrow = ""

mysql = None

## Oeffnen der Datenbankverbindung
mysql = MySQLdb.connect(host="127.0.0.1",user="root",passwd="pi",db="biss-db")

with mysql:
    cur = mysql.cursor()
    cur.execute("SELECT * FROM gammascout")
    logfile = open('/Gammascout/log.csv', "rb")
    read = csv.reader(logfile)
    count = 0
    for row in read:
        ## aeltere Daten ueberspringen
        currdatetime = row[1]
        if lastdatetime < currdatetime and count > 0:
            ## Daten schreiben
            ## print row
            datum = row[1]
            cpm = row[4]
            cpm = float(cpm)
            cps = row[5]
            cps = float(cps)
            dosis = cpm2uSv(cps)
            newrow = row[0]+","+row[1]+","+row[2]+","+row[3]+","+row[4]+","+row[5]+","+str(dosis)+"\n"
            ## print newrow
            biglog.write(newrow)
            ## print count
            cur.execute("INSERT INTO `biss-db`.`gammascout` (`datum`, `cpm`, `cps`, `dosis` ) VALUES ('%s', '%f', '%f', '%f')" % (datum, cpm, cps, dosis))
            mysql.commit()
        count = count + 1

    if newrow <> "":
        lastlog = open('/Gammascout/lastlog.csv', "w")
        lastlog.write(newrow)
        lastlog.close()

biglog.close()
logfile.close()

if lastdaysync == 1:
    # biglog packen fuer upload
    os.system("tar -czf /Gammascout/log.tar.gz /Gammascout/biglog.csv")

## geraet nach 2 tagen leeren, wg. uebertragungsdauer + uhrzeit sync
if count > 2880:
    os.system("/usr/local/GammaScoutUtil-0.04/gammascoututil -d /dev/ttyUSB0 clearlog:")
    os.system("/usr/local/GammaScoutUtil-0.04/gammascoututil -d /dev/ttyUSB0 synctime:")

#
# Werte der letzten 24h minutengenau ausgeben
#

cur = mysql.cursor()
cur.execute("SELECT dosis FROM ( SELECT * FROM gammascout ORDER BY id DESC LIMIT 1440 ) sub ORDER BY id ASC")
dose = cur.fetchall()

cur = mysql.cursor()
cur.execute("SELECT datum FROM ( SELECT * FROM gammascout ORDER BY id DESC LIMIT 1440 ) sub ORDER BY id ASC")
datumuhrzeit = cur.fetchall()

x = datumuhrzeit
y = dose

mindat = p.amin(x); maxdat = p.amax(x)
ymax = p.amax(y)
if ymax < 0.3:
    ymax = 0.3

fig, ax = plt.subplots()
ax.plot(x, y, label="Gammamonitor" )
plt.plot([mindat, maxdat], [mwmeine, mwmeine], 'g', lw=2)
plt.plot([mindat, maxdat], [gwgorleben, gwgorleben], 'y', lw=2)
plt.plot([mindat, maxdat], [gwallgemein, gwallgemein], 'r', lw=2)

ax.set_xlim(mindat, maxdat)

ax.xaxis.set_major_locator( mdates.MinuteLocator() )
ax.xaxis.set_major_formatter( mdates.DateFormatter('%d.%m.\n%H:%M'))
start, end = ax.get_xlim()
ax.xaxis.set_ticks(np.arange(start, end+0.01, (end-start)/10))

ax.set_ylabel('Ortsdosisleistung in Mikrosievert pro Stunde')
ax.set_xlabel('Zeitpunkt')
ax.set_title ('Werte der letzten 24 Stunden')
ax.set_ylim(0,ymax)

ax.format_xdata = mdates.DateFormatter('%d.%m.%Y %H:%M')
ax.grid(True)

fig.autofmt_xdate()

plt.savefig('/Gammascout/24h.png')

if lastdaysync == 1:
    #
    # Werte des vortags minutengenau ausgeben
    #

    cur = mysql.cursor()
    cur.execute("SELECT datum FROM ( SELECT * FROM gammascout WHERE date(datum) = (date(current_date - interval 1 day)) ) sub ORDER BY id ASC")
    datumuhrzeit = cur.fetchall()

    cur = mysql.cursor()
    cur.execute("SELECT dosis FROM ( SELECT * FROM gammascout WHERE date(datum) = (date(current_date - interval 1 day)) ) sub ORDER BY id ASC")
    dose = cur.fetchall()

    x = datumuhrzeit
    y = dose

    mindat = p.amin(x); maxdat = p.amax(x)
    ymax = p.amax(y)
    if ymax < 0.3:
        ymax = 0.3

    fig, ax = plt.subplots()
    ax.plot(x, y)
    plt.plot([mindat, maxdat], [mwmeine, mwmeine], 'g', lw=2)
    plt.plot([mindat, maxdat], [gwgorleben, gwgorleben], 'y', lw=2)
    plt.plot([mindat, maxdat], [gwallgemein, gwallgemein], 'r', lw=2)

    ax.set_xlim(mindat, maxdat)

    ax.xaxis.set_major_locator( mdates.MinuteLocator() )
    ax.xaxis.set_major_formatter( mdates.DateFormatter('%d.%m.\n%H:%M'))
    start, end = ax.get_xlim()
    ax.xaxis.set_ticks(np.arange(start, end+0.01, (end-start)/10))

    ax.set_ylabel('Ortsdosisleistung in Mikrosievert pro Stunde')
    ax.set_xlabel('Zeitpunkt')
    ax.set_title ('Werte von gestern')
    ax.set_ylim(0,ymax)

    ax.format_xdata = mdates.DateFormatter('%d.%m.%Y %H:%M')
    ax.grid(True)
    fig.autofmt_xdate()

    plt.savefig('/Gammascout/gestern.png')

    #    
    # stundenmittelwerte des vortags ausgeben
    #

    cur = mysql.cursor()
    cur.execute("SELECT datum FROM gammascout WHERE date(datum) = (date(current_date - interval 1 day)) GROUP BY hour(datum) ASC")
    datumuhrzeit = cur.fetchall()

    cur = mysql.cursor()
    cur.execute("SELECT round(AVG(dosis),3) FROM gammascout WHERE date(datum) = (date(current_date - interval 1 day)) GROUP BY hour(datum) ASC")
    dose = cur.fetchall()

    x = datumuhrzeit
    y = dose

    mindat = p.amin(x); maxdat = p.amax(x)
    ymax = p.amax(y)
    if ymax < 0.3:
        ymax = 0.3

    fig, ax = plt.subplots()
    ax.plot(x, y)
    plt.plot([mindat, maxdat], [mwmeine, mwmeine], 'g', lw=2)
    plt.plot([mindat, maxdat], [gwgorleben, gwgorleben], 'y', lw=2)
    plt.plot([mindat, maxdat], [gwallgemein, gwallgemein], 'r', lw=2)

    ax.set_xlim(mindat, maxdat)

    ax.xaxis.set_major_locator( mdates.HourLocator() )
    ax.xaxis.set_major_formatter( mdates.DateFormatter('%H'))
    start, end = ax.get_xlim()

    ax.set_ylabel('Ortsdosisleistung in Mikrosievert pro Stunde')
    ax.set_xlabel('Stunde')
    ax.set_title ('Stundenmittelwerte von gestern')
    ax.set_ylim(0,ymax)

    ax.format_xdata = mdates.DateFormatter('%H')
    ax.grid(True)
    fig.autofmt_xdate()

    plt.savefig('/Gammascout/gesternph.png')

    #
    # Mittelwerte der letzten 31 Tage ausgeben
    #

    cur = mysql.cursor()
    cur.execute("SELECT date(datum) FROM gammascout WHERE datum BETWEEN (date(current_date - interval 32 day)) AND (date(current_date)) GROUP BY date(datum) ASC")
    datumuhrzeit = cur.fetchall()

    cur = mysql.cursor()
    cur.execute("SELECT round(AVG(dosis),3) FROM gammascout WHERE datum BETWEEN (date(current_date - interval 32 day)) AND (date(current_date)) GROUP BY date(datum) ASC")
    dose = cur.fetchall()

    x = datumuhrzeit
    y = dose

    mindat = p.amin(x); maxdat = p.amax(x)
    ymax = p.amax(y)
    if ymax < 0.3:
        ymax = 0.3

    fig, ax = plt.subplots()
    ax.plot(x, y)
    plt.plot([mindat, maxdat], [mwmeine, mwmeine], 'g', lw=2)
    plt.plot([mindat, maxdat], [gwgorleben, gwgorleben], 'y', lw=2)
    plt.plot([mindat, maxdat], [gwallgemein, gwallgemein], 'r', lw=2)

    ax.set_xlim(mindat, maxdat)

    ax.xaxis.set_major_locator( mdates.DateLocator() )
    ax.xaxis.set_major_formatter( mdates.DateFormatter('%d.%m.'))
    start, end = ax.get_xlim()
    ax.xaxis.set_ticks(np.arange(start, end+0.01, (end-start)/10) )

    ax.set_ylabel('Ortsdosisleistung in Mikrosievert pro Stunde')
    ax.set_xlabel('Tag')
    ax.set_title ('Mittelwerte der letzten 31 Tage')
    ax.set_ylim(0,ymax)

    ax.format_xdata = mdates.DateFormatter('%d.%m.%Y')
    ax.grid(True)
    fig.autofmt_xdate()

    plt.savefig('/Gammascout/31d.png')

mysql.close()

#
# Upload der Daten
#

session = ftplib.FTP('SERVER','USER','PASSWORT')
file = open('/Gammascout/24h.png','rb')
session.storbinary('STOR 24h.png', file)
file.close()

if lastdaysync == 1:
    file = open('/Gammascout/gestern.png','rb')
    session.storbinary('STOR gestern.png', file)
    file.close()
    file = open('/Gammascout/31d.png','rb')
    session.storbinary('STOR 31d.png', file)
    file.close()
    file = open('/Gammascout/gesternph.png','rb')
    session.storbinary('STOR gesternph.png', file)
    file.close()
    file = open('/Gammascout/log.tar.gz','rb')
    session.storbinary('STOR log.tar.gz', file)
    file.close()
    # autom. reboot nach mitternacht
    os.system("sudo shutdown -r now &")

session.quit()

Jetzt fehlt nur noch die automatische Anmeldung im Wlan:

(Der Pi macht das nicht automatisch…)
Unter /etc/network muss die Datei interfaces wie folgt angepasst werden:

auto lo
auto wlan0

iface lo inet loopback
iface eth0 inet dhcp

allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp

Und jetzt noch die Datei /etc/wpa_supplicant/wpa_supplicant.conf
Hier werden die Einstellungen für das Wlan eingetragen.

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
        ssid="HIER STEHT IHRE WLAN-SSID"
        psk="IHR WLAN-KENNWORT"
        proto=RSN
        key_mgmt=WPA-PSK
        pairwise=AES
        auth_alg=OPEN
}

Wie schon geschrieben: Die Scripte werden im Laufe der Zeit noch verändert und die Änderungen an dieser Stelle dokumentiert.