#!/usr/bin/env python3
import argparse
import logging
import time
import platform
import math
import json
from datetime import datetime
from subprocess import check_output, CalledProcessError
import paho.mqtt.client as mqtt

global logger

def read_grove():
    out = check_output(['grove/grove'])
    logger.debug("grove/grove output: %r", out)
    return json.loads(out.decode('utf-8'))

def read_tmp006():
    out = check_output(['tmp006/tmp006'])
    logger.debug("tmp006/tmp006 output: %r", out)
    return json.loads(out.decode('utf-8'))

def main():
    logging.basicConfig()
    global logger
    logger = logging.getLogger('collector')

    parser = argparse.ArgumentParser(prog="collector")

    parser.add_argument('--debug', '-d',
                        action='store_const',
                        const=logging.DEBUG,
                        dest='logging')

    parser.add_argument('--quiet', '-q',
                        action='store_const',
                        const=logging.WARNING,
                        dest='logging')

    parser.add_argument('--interval', '-i', default=60, type=int)
    parser.add_argument('--broker', '-b', default="localhost", type=str)
    parser.add_argument('--broker-port', '-p', default=1883, type=int)
    parser.add_argument('--broker-user', '-U', type=str)
    parser.add_argument('--broker-password', '-P', type=str)

    parser.add_argument('--mock', action='store_true', default=False,
                        help='Send mock temperature measurement values')

    parser.add_argument('id', type=str,
                        help='Node identifier')

    parser.set_defaults(logging=logging.INFO)
    args = parser.parse_args()
    logging.getLogger().setLevel(args.logging)

    logger.debug("args=%r", args)

    client = mqtt.Client()

    if args.broker_user:
        client.username_pw_set(args.broker_user, args.broker_password)

    client.connect(args.broker, args.broker_port)
    client.loop_start()

    logger.debug("client=%r", client)

    def topic(n):
        return "node/" + args.id + "/" + n

    while True:
        logger.debug("Measuring ...")

        values = {}

        ## TODO MEASUREMENTS HERE
        if args.mock:
            values['temperature'] = "%.2f" % (100.0 + math.sin(time.time() / 600) * 5,)
            logger.info("Sending mock temperature %s°C", values['temperature'])
        else:
            try:
                values['light'] = read_grove()['lux']
            except CalledProcessError:
                logger.error("Failed to read Grove light sensor")

            try:
                values['temperature'] = read_tmp006()['object']
            except CalledProcessError:
                logger.error("Failed to read TMP006 temperature sensor")

        logger.debug("values: %r", values)

        for k, v in values.items():
            t = topic("sensor/" + k)
            logger.debug("Sending %s = %s", t, v)
            client.publish(t,
                           payload=json.dumps(
                               {'value': v,
                                'time': datetime.now().isoformat()}))

        t = topic("active")
        logger.debug("Sending alive signal to %s", t)
        client.publish(t, payload=datetime.now().isoformat())

        logger.debug("Sleeping for %ds", args.interval)
        time.sleep(args.interval)

if __name__ == "__main__":
    main()
