Archiv der Kategorie: Wissenswertes

AirPi-Daemon Startscript

Der AirPi-Daemon „airpi.py“ von Tom Hartley (siehe https://github.com/tomhartley/AirPi) lässt sich mit folgendem Shell-Script leichter starten und stoppen. Das Script startet airpi.py im Hintergrund und leitet alle stderr und stdout Ausgaben in ein Logfile um.

Start und Stop des AirPi-Daemons:

airpid.sh start
airpid.sh stop

airpid.sh

#!/bin/bash

### BEGIN INIT INFO
# Provides:          airpid.sh
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: AirPi Weather Station Daemon
# Description:       This service is used to read sensor data from AirPi and upload to Xively.com
### END INIT INFO

case "$1" in
  start)
    echo "Starting AirPi Daemon"
    ## cd into airpi directory to make sure all files are found
    cd /home/pi/workspace/AirPi;
    ## start airpi.py using script for unbuffered output and redirect output to logfile
    script -c "sudo python airpi.py" >> airpi.log 2>&1 &
  ;;
  stop)
    echo "Stopping AirPi Daemon"
    ## serach for airpi.py process and stop it using kill
    sudo kill `pgrep -f airpi.py`
  ;;
  *)
    echo "Usage: /etc/init.d/airpi.sh start|stop"
    exit 1
  ;;
esac

exit 0

Wichtig ist, dass airpi.py mit sudo unter Root laufen muss!

Ein Blick in das laufende Logfile von airpi.py lässt zB: tail -f sensor.log zu:

tail -f sensor.log 

Success: Loaded sensor plugin BMP085-temp
Success: Loaded sensor plugin BMP085-pres
Success: Loaded sensor plugin BMP085-alt
Success: Loaded sensor plugin MCP3008
Success: Loaded sensor plugin DHT22
Success: Loaded sensor plugin DHT22-temp
Success: Loaded sensor plugin LDR
Success: Loaded sensor plugin LDR_LUX
Success: Loaded sensor plugin TGS2600
Success: Loaded sensor plugin MiCS-2710
Success: Loaded sensor plugin MiCS-5525
Success: Loaded sensor plugin Mic
Success: Loaded output plugin Print
Success: Loaded output plugin Xively
...

Autostart vom AirPi-Daemon

sudo nano /etc/rc.local

Durch Hinzufügen folgender Zeile, wird der AirPi-Daemon nach jedem Reboot automatisch gestartet:

/home/pi/workspace/AirPi/airpid.sh

Liniendiagramm aus Xively-Daten mit Highcharts

Liniendiagramm 1

<script src="http//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/stock/highstock.js"></script>

<div id="chart1" style="height: 300px;"></div>

<script>
jQuery(function() {
    feedid = '******';
    key = '******';
    channel = 'Air_Temperature';
    interval = 900;
    days = 7;

    start_date = new Date();
    start_date.setHours(start_date.getHours() - 24*days); 

    // load data from xively feed
	jQuery.getJSON('http://api.xively.com/v2/feeds/'+feedid+'/datastreams/'+channel+'.json?start='+start_date+'&interval='+interval+'?key='+key, function(data) {
        var xively_datapoints = data.datapoints;
        var chartdata = [];
        // convert data format from xively to highcharts
        for (i = 0; i < xively_datapoints.length; i++) {
            chartdata.push([
                Date.parse(xively_datapoints[i].at),
                parseFloat(xively_datapoints[i].value)
            ]);
        }

		// create the chart using highcharts line diagram
		jQuery('#chart1').highcharts('StockChart', {
			rangeSelector : { selected : 1 },
			 exporting: {
                    chartOptions:{
	                   yAxis: { labels: { style: { color: '#000', fontSize: '14px'} } }
		            }
             },
			series : [{
				name : channel,
				data : chartdata,
				tooltip: { valueDecimals: 2 }
			}]
		});
	});
});
</script>

Liniendiagramm 2

 

<script src="http//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/stock/highstock.js"></script>

<div id="chart2" style="height: 300px;"></div>

<script>
jQuery(function() {
    feedid = '******';
    key = '*****';
    channel = 'Air_Temperature';
    interval = 900;
    days = 7;

    start_date = new Date();
    start_date.setHours(start_date.getHours() - 24*days); 

    // load data from xively feed
    jQuery.getJSON('http://api.xively.com/v2/feeds/'+feedid+'/datastreams/'+channel+'.json?start='+start_date+'&interval='+interval+'?key='+key, function(data) {
		var xively_datapoints = data.datapoints;
		var chartdata = [];
		// convert data format from xively to highcharts
		for (i = 0; i < xively_datapoints.length; i++) {
			chartdata.push([
				Date.parse(xively_datapoints[i].at),
				parseFloat(xively_datapoints[i].value)
			]);
		}
			// create the chart using highcharts line diagram
		jQuery('#chart2').highcharts({
			title: {
				text: 'Aktuelle Temperatur',
				x: -20
			},
			subtitle: {
				text: 'Quelle: Xively.com',
				x: -20
			},
                        xAxis: {
                          type: 'datetime',
                        },
			yAxis: {
				title: {
						text: 'Temperatur (C)',
				},
				plotLines: [{
						value: 0,
						width: 1,
						color: '#808080',
				}]
			},
			tooltip: {
				valueSuffix: 'C',
			},
			series: [{
				name: channel,
				data: chartdata,
				tooltip: { valueDecimals: 2 },
			}],
		});

	});
});

Anzeige von Xively-Daten mit Google Charts

Anzeige von Xively-Daten mit Hilfe von Google-Charts „Gauge“:

<script src="https://www.google.com/jsapi?ext.js"></script>

<script>
var feedid = "*****";
var key = "*****";
var chart_data;

google.load('visualization', '1', {packages:['gauge']});
google.setOnLoadCallback(initChart);

function loadData(chart, options, channel_name) {
    var p;     // variable for the data point
    jQuery.getJSON('https://api.xively.com/v2/feeds/'+feedid+'/datastreams/'+channel_name+'.json?&key='+key+'&callback=?', function(data) {
        p = data.current_value;
        if (p) {
            console.log(channel_name+': '+p);
            console.log(data);
            p = (p/1);
            chart_data.setValue(0, 0, data.unit.symbol);
            // chart_data.setValue(0, 0, channel_name);
            chart_data.setValue(0, 1, p);
            console.log(chart_data);
            chart.draw(chart_data, options);
        }
    });
}

function initChart() {
    chart_data = new google.visualization.DataTable();
    chart_data.addColumn('string', 'Label');
    chart_data.addColumn('number', 'Value');
    chart_data.addRows(1);

    // Air_Temperature
    chart_air_temperature = new google.visualization.Gauge(document.getElementById('chart_air_temperature'));
    options = {
        width: 200, height: 200,
        redColor: 'lightblue', redFrom: -20, redTo: 0,
        yellowColor: 'lightred', yellowFrom: 40, yellowTo: 60,
        greenColor: 'lightgreen', greenFrom: 18, greenTo: 25,
        min: -20, max: 60,
        majorTicks: [-20, -10, "0", 10, 20, 30, 40, 50, 60],
        minorTicks: 10,
        animation: {duration: 400, easing: 'out',},
    };
    loadData(chart_air_temperature, options, 'Air_Temperature');
    setInterval(function() { loadData(chart_air_temperature, options, 'Air_Temperature'); }, 15000);

    // Relative_Humidity
    chart_relative_humidity = new google.visualization.Gauge(document.getElementById('chart_relative_humidity'));
    options2 = {
        width: 200, height: 200,
        yellowColor: 'lightblue', yellowFrom: 0, yellowTo: 40,
        greenColor: 'lightgreen', greenFrom: 40, greenTo: 70,
        redColor: 'lightred', redFrom: 70, redTo: 100,
        min: 0, max: 100,
        majorTicks: ["0", 10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
        minorTicks: 5,
        animation: {duration: 400, easing: 'out',},
    };
    loadData(chart_relative_humidity, options2, 'Relative_Humidity');
    setInterval(function() { loadData(chart_relative_humidity, options2, 'Relative_Humidity'); }, 15000);
}
</script>

Anzeige von Xively-Daten mit Highcharts

Anzeige von Xively.com-Daten auf einer Webseite mit Hilfe von Highcharts und JQuery:

<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/highcharts-more.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>

Temperatur-Anzeige

<script>
jQuery( document ).ready(function( $ ) {
    var feedid = "*****";
    var key = "*****";
    
    // Air Temperature
    $('#chart_air_temperature').highcharts({
        chart: {
            type: 'gauge',
            alignTicks: false,
            plotBackgroundColor: null,
            plotBackgroundImage: null,
            plotBorderWidth: 0,
            plotShadow: false,
        },
        title: { text: 'Air Temperature' },
        pane: { startAngle: -150, endAngle: 150 },            
        yAxis: [{
            min: -20, max: 60,
            tickPosition: 'outside',
            minorTickPosition: 'outside',
            lineColor: '#339', tickColor: '#339', minorTickColor: '#339',
            offset: -20,
            labels: { distance: 12, rotation: 'auto' },
            tickLength: 5, minorTickLength: 5, lineWidth: 2,
            endOnTick: true,
            plotBands: [
                { color: 'lightblue', from: -20, to: 0, innerRadius: '30%', outerRadius: '40%' },
                { color: 'lightgreen', from: 18, to: 25, innerRadius: '30%', outerRadius: '40%' },
                { color: '#ff9999', from: 38, to: 60, innerRadius: '30%', outerRadius: '40%' }],
        }, {
            min: -20 * 1.8 + 32, max: 60 * 1.8 + 32,
            lineColor: '#933', tickColor: '#933', minorTickColor: '#933',
            tickLength: 5, minorTickLength: 5, lineWidth: 2,
            labels: { distance: -20, rotation: 'auto' },
            offset: -30,
            endOnTick: false,
        }],
        series: [{
            name: 'Air_Temperature',
            data: [0], // start value
            dataLabels: {
                formatter: function () {
                    var c = this.y;
                    var f = c * 1.8 + 32;
                    return ''+c+'C/'+f+'F';
                },
                backgroundColor: {
                    linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                    stops: [ [0, '#DDD'], [1, '#FFF'] ]
                }
            },
            tooltip: { valueSuffix: 'C' }
        }]
    
    },
    function(chart) {
        setInterval(function() {
            $.getJSON('http://api.xively.com/v2/feeds/'+feedid+'/datastreams/Air_Temperature.json?key='+key, function(data) {
                var value = Math.round(data.current_value);
                var point = chart.series[0].points[0];
                point.update(value);
             });
        }, 3000);
    });
});
</script>

Anzeige der Lautstärke

<script>
jQuery( document ).ready(function( $ ) {
    var feedid = "*****";
    var key = "*****";

    
    // Volume
    $('#chart_volume').highcharts({
        chart: {
            type: 'gauge',
            plotBorderWidth: 1,
            plotBackgroundColor: {
                linearGradient: { x1: 0, y1: 0,  x2: 0, y2: 1 },
                stops: [ [0, '#FFF4C6'], [0.3, '#FFFFFF'], [1, '#FFF4C6'] ]
            },
            plotBackgroundImage: null,
            height: 200
        },
        title: { text: 'VU meter' },
        pane: [{
            startAngle: -45, endAngle: 45,
            background: null,
            center: ['50%', '145%'],
            size: 300
        }],                       
        yAxis: [{
            min: -20,
            max: 1000,
            minorTickPosition: 'outside',
            tickPosition: 'outside',
            labels: {
                rotation: 'auto',
                distance: 20
            },
            plotBands: [{
                color: '#C02316', from: 500, to: 1000,
                innerRadius: '100%', outerRadius: '105%'
            }],
            pane: 0,
            title: {
                text: 'VU Mono',
                y: -40
            }
        },],  
        plotOptions: {
            gauge: {
                dataLabels: {
                    enabled: false
                },
                dial: {
                    radius: '100%'
                }
            }
        },
        series: [{
            data: [-20],
            yAxis: 0
        }]
    
    },
    
    // Let the music play
    function(chart) {
        setInterval(function() {
            $.getJSON('http://api.xively.com/v2/feeds/'+feedid+'/datastreams/Volume.json?key='+key, function(data) {
                var value = Math.round(data.current_value);
                // console.log(value);
                var point = chart.series[0].points[0];
                point.update(value, false);
                chart.redraw();
            });
        }, 500);
        
    });
});
</script>