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)
|