-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
129 lines (107 loc) · 3.97 KB
/
app.py
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/usr/bin/python
#
from __future__ import print_function
from metar import Metar
import os
import sys
import getopt
import string
import math
import json
import logging
import time
import random
import numpy as np
from metpy.units import units
import metpy.calc as mpcalc
import paho.mqtt.client as mqtt
try:
from urllib2 import urlopen
except:
from urllib.request import urlopen
BASE_URL = "http://tgftp.nws.noaa.gov/data/observations/metar/stations"
MQTT_PUB_ROOT = os.getenv("MQTT_PUB_ROOT", "METAR")
MQTT_CLIENTID = os.getenv("MQTT_CLIENTID", f'metar-{random.randint(0, 1000)}')
MQTT_HOST = os.getenv("MQTT_HOST", "")
MQTT_PORT = os.getenv("MQTT_PORT", "1883")
MQTT_USER = os.getenv("MQTT_USER", "")
MQTT_PASS = os.getenv("MQTT_PASS", "")
MQTT_KEEPALIVE = os.getenv("MQTT_KEEPALIVE", "60")
METAR_SNOOZE = os.getenv("METAR_SNOOZE", "300")
Log_Format = "%(levelname)s %(asctime)s - %(message)s"
logging.basicConfig(
stream=sys.stdout, filemode="w", format=Log_Format, level=logging.ERROR
)
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
def dump(obj):
for attr in dir(obj):
print("obj.%s = %r" % (attr, getattr(obj, attr)))
def truncate(f, n):
return math.floor(f * 10 ** n) / 10 ** n
def mqtt_publish(station, dewpoint, temperature, rh, pressure):
data = {
"station": station,
"dewpoint": dewpoint,
"temp": temperature,
"humidity": rh,
"pressure": pressure,
}
logger.debug("Write points: {0}".format(data))
client = mqtt.Client(client_id=MQTT_CLIENTID, clean_session=None, userdata=None,
transport="tcp", reconnect_on_failure=True) # create new instance
client.connect(host=MQTT_HOST, port=int(MQTT_PORT)) # connect to broker
client.publish(MQTT_PUB_ROOT, payload=json.dumps(data)) # publish
def fetch_metar():
stations = ["KMWO", "KHAO"]
for name in stations:
url = "%s/%s.TXT" % (BASE_URL, name)
logger.debug(f"Fetching {url}")
try:
response = urlopen(url, timeout=30)
except Metar.ParserError as exc:
logger.debug("METAR code: {0}".format(line))
logger.debug(string.join(exc.args, ", "), "\n")
except:
import traceback
logger.debug(traceback.format_exc())
logger.debug("Error retrieving", name, "data")
else:
report = ""
for line in response:
if not isinstance(line, str):
line = line.decode() # convert Python3 bytes buffer to string
if line.startswith(name):
report = line.strip()
obs = Metar.Metar(line)
logger.debug(obs)
try:
temp = obs.temp.value("C")
except:
temp = 0
try:
dewp = obs.dewpt.value("C")
except:
dewp = temp
if dewp != 0 and temp != 0:
relhumcalc = str(mpcalc.relative_humidity_from_dewpoint(
temp * units.celsius, dewp * units.celsius) * units.percent * 100)
rawrelhum = relhumcalc.split(" ")
hum = str(round(float(rawrelhum[0]), 2))
else:
hum = 0
pressure = truncate(obs.press._value * 33.864, 2)
logger.debug(
f"MQTT -> station_id: {obs.station_id}, dewp: {dewp}, temp: {temp}, hum: {hum}, pressure: {pressure}"
)
mqtt_publish(
obs.station_id, dewp, temp, hum, pressure
)
break
if not report:
logger.debug("No data for ", name)
if __name__ == "__main__":
while True:
fetch_metar()
logger.debug("Sleeping till next go around")
time.sleep(int(METAR_SNOOZE))