summaryrefslogtreecommitdiff
path: root/weather-logger-receiver
blob: 389a9de061375357ad500a20d03040931d83a768 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/env python3

import logging
import os
import signal
import sqlite3
import sys
import time
import yaml

from RFXtrx import PySerialTransport


def setup_database(path="weather.db"):
    db_connection = sqlite3.connect(path)
    db_cursor = db_connection.cursor()
    try:
        db_cursor.execute("CREATE TABLE weather( \
                                          id INTEGER PRIMARY KEY, \
                                          timestamp DATETIME, \
                                          handle TEXT, \
                                          temperature FLOAT, \
                                          humidity FLOAT);")
    except sqlite3.OperationalError:
        pass

    return db_connection


def setup_serial(device="/dev/ttyUSB0"):
    serial_connection = PySerialTransport(device)
    serial_connection.reset()

    return serial_connection


def load_known_devices(location, path="known-devices.yaml"):
    known_devices = None
    with open(path, "r") as f:
        known_devices = yaml.safe_load(f.read())

    return known_devices[location]


def add_data_to_db(data, handle, db_connection):
    db_cursor = db_connection.cursor()
    db_cursor.execute(f"INSERT INTO weather \
                        (timestamp, handle, temperature, humidity) \
                        VALUES (  {int(time.time())}, \
                                \"{handle}\", \
                                  {data.values['Temperature']}, \
                                  {data.values['Humidity']})")
    db_connection.commit()


def loop(serial_connection, db_connection, logger):
    while True:
        logger.info("(Re-)Starting receiver loop")

        data = serial_connection.receive_blocking()
        
        if data is None:
            logger.info("Received no data")
            continue

        logger.info(data)

        try:
            if data.device.id_string not in known_devices:
                logger.info(f"Unknown device with id {device_id} and type {device_type}, ignoring")
                continue
        except:
            logger.info("Device ID not found, likely no SensorEvent, ignoring")
            continue

        handle = known_devices[data.device.id_string]["handle"]
        
        add_data_to_db(data, handle, db_connection)


if __name__ == "__main__":
    logger = logging.getLogger("weather-logger-receiver")
    logging.basicConfig(format='%(asctime)-2s %(levelname)-8s %(message)s',
                        datefmt='%Y-%m-%dT%H:%M:%S',
                        level=logging.INFO)

    assert len(sys.argv) == 2
    location = sys.argv[1]
    known_devices = load_known_devices(location=location)
    logger.info(f"Loaded known devices for location {location}")

    db_connection = setup_database()
    logger.info("Set up database")

    serial_connection = setup_serial()
    logger.info("Set up serial connection")

    def shutdown(*args):
        logger.info("Shutting down")
        serial_connection.close()
        db_connection.close()
        sys.exit(0)

    signal.signal(signal.SIGINT, shutdown)
    signal.signal(signal.SIGTERM, shutdown)

    try:
        loop(serial_connection, db_connection, logger)
    except Exception as e:
        logger.error(f"Exception: {e}")
    finally:
        shutdown(serial_connection, db_connection, logger)