"""
piweather.py

Internetowy monitor temperatury-wilgotnośi wykorzystujący Raspberry Pi oraz DHT11.

Autor: Mahesh Venkitachalam
"""

from bottle import route, run, request, response
from bottle import static_file
import random, argparse
import RPi.GPIO as GPIO
from time import sleep  
import Adafruit_DHT

@route('/hello')
def hello():
    return "Witaj, świecie Bottle!"

@route('/<filename:re:.*\.js>')
def javascripts(filename):
    return static_file(filename, root='flot')

@route('/plot')
def plot():
    return '''
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<title>PiWeather</title>
    <style>
     .demo-placeholder {
	width: 90%;
	height: 50%;
    }
    </style>
	<script language="javascript" type="text/javascript" 
       src="jquery.js"></script>
	<script language="javascript" type="text/javascript" 
       src="jquery.flot.js"></script>
    <script language="javascript" type="text/javascript" 
       src="jquery.flot.time.js"></script>
    <script language="javascript" type="text/javascript">

$(document).ready(function() {

    // opcje wykresu
    var options = {
        series: {
		  lines: {
			show: true
		  },
		  points: {
			show: true
		  }
		},
        grid: {
		  clickable: true
		},
	    yaxes: [{min: 0, max: 100}],
        xaxes: [{min: 0, max: 100}],
    };
    
    // tworzenie pustego wykresu
	var plot = $.plot("#placeholder", [[]], options);

    // inicjowanie tablic danych
    var RH = [];
    var T = []; 
    var timeStamp = [];    
    // uzyskiwanie danych z serwera
    function getData() {
        // wywołanie zwrotne AJAX 
        function onDataReceived(jsonData) {    
            timeStamp.push(Date());
            // dodawanie danych RH
			RH.push(jsonData.RH);
            // usuwanie najstarszej wartości
            if (RH.length > 100) {
              RH.splice(0, 1);
            }
            // dodawanie danych T
            T.push(jsonData.T);
            // usuwanie najstarszej wartości
            if (T.length > 100) {
              T.splice(0, 1);
            }
            s1 = [];
            s2 = [];
            for (var i = 0; i < RH.length; i++) {
                s1.push([i, RH[i]]);
                s2.push([i, T[i]]);
            }
            // ustawianie do rysowania wykresu
            plot.setData([s1, s2]);
            plot.draw();
		}

        // procedura obsługi błędów AJAX
        function onError(){
            $('#ajax-panel').html('<p><strong>błąd Ajax!</strong> </p>');
        }
        
        // wykonanie wywołania AJAX
		$.ajax({
		    url: "getdata",
			type: "GET",
			dataType: "json",
			success: onDataReceived,
            error: onError
		});        
     }

     // definiowanie funkcji aktualizacji
	 function update() {
        // uzyskanie danych
        getData();
        // ustawienie limitu czasu
		setTimeout(update, 1000);
	 }

     // wywołanie aktualizacji
	 update();
 
     // definiowanie procedury obsługi kliknięcia dla przycisku sterowania diodą LED
     $('#ckLED').click(function() {
         var isChecked = $("#ckLED").is(":checked") ? 1:0;
         $.ajax({
           url: '/ledctrl',
           type: 'POST',
           data: { strID:'ckLED', strState:isChecked }
         });
      });

     $("#placeholder").bind("plotclick", function (event, pos, item) {
          if (item) {
            plot.highlight(item.series, item.datapoint);
            var strData = ' [Kliknięte dane: ' + 
                           timeStamp[item.dataIndex] + ': T = ' + 
                           T[item.dataIndex] + ', RH = ' + RH[item.dataIndex]
                          + ']';
            $('#data-values').html(strData);
          }
     });
});

</script>
</head>

<body>
	<div id="header">
		<h2>Temperatura/Wilgotność</h2>
	</div>

	<div id="content">
		<div class="demo-container">
			<div id="placeholder" class="demo-placeholder"></div>
		</div>
        <div id="ajax-panel"> </div>
	</div>
    <div>
      <input type="checkbox" id="ckLED" value="on">Włączenie podświetlenia.
      <span id="data-values"> </span>
    </div>
    
</body>
</html>
'''
    
@route('/getdata', method='GET')
def getdata():
    RH, T = Adafruit_DHT.read_retry(Adafruit_DHT.DHT11, 23)
    # zwracanie słownika
    return {"RH": RH, "T": T}
    
@route('/ledctrl', method='POST')
def ledctrl():
    val = request.forms.get('strState')
    on = bool(int(val))
    GPIO.output(18, on) 

# funkcja main()
def main():
    print 'uruchamianie programu piweather...'
    # tworzenie parsera
    parser = argparse.ArgumentParser(description="PiWeather...")
    # dodawanie oczekiwanych argumentów
    parser.add_argument('--ip', dest='ipAddr', required=True)
    parser.add_argument('--port', dest='portNum', required=True)

    # parsowanie argumentów
    args = parser.parse_args()

    # ustawianie GPIO
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(18, GPIO.OUT)
    GPIO.output(18, False)
    # uruchamianie serwera
    run(host=args.ipAddr, port=args.portNum, debug=True)

# wywołanie main
if __name__ == '__main__':
    main()
