-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathapp.py
More file actions
199 lines (167 loc) · 8.26 KB
/
app.py
File metadata and controls
199 lines (167 loc) · 8.26 KB
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
from configparser import ConfigParser
from datetime import datetime
from decimal import Decimal
import paho.mqtt.client as mqtt
from mqtt.MQTTConfig import MQTTConfig
# see https://learn.adafruit.com/adafruit-bme280-humidity-barometric-pressure-temperature-sensor-breakout/python-circuitpython-test
import board
import busio
import time
import adafruit_bme280
class App:
def __init__(self):
pass
@staticmethod
def on_connect(client, userdata, flags, rc) -> None:
"""
The callback for when the client receives a CONNACK response from the server.
:param client: The client instance for this callback
:param userdata: The private user data as set in Client() or userdata_set()
:param flags: Response flags sent by the broker
:param rc: The connection result
"""
print("Connected with result code " + str(rc))
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
client.subscribe("$SYS/#")
@staticmethod
def on_disconnect(client, userdata, rc) -> None:
"""
Called when the MQTT client disconnects.
:param client: The client instance for this callback
:param userdata: The private user data as set in Client() or userdata_set()
:param rc:
:return:
"""
if rc != 0:
print('Unexpected disconnection. Reconnecting.')
client.reconnect()
@staticmethod
def on_publish(client, userdata, mid) -> None:
"""
Called when a message that was to be sent using the publish() call has completed transmission to the broker.
:param client: The client instance for this callback
:param userdata: The private user data as set in Client() or userdata_set()
:param mid: The mid variable returned from corresponding publish() call to allow outgoing messages to be tracked
"""
print('published {userdata} (mid: {mid})'.format(userdata=userdata, mid=mid))
@staticmethod
def main():
"""
Main executable method.
:return:
"""
config = ConfigParser()
config.read('config.ini')
elevation = Decimal(config['GPS']['elevation'])
elevation_units = config['GPS']['elevation_units']
latitude = Decimal(config['GPS']['latitude_decimal'])
longitude = Decimal(config['GPS']['longitude_decimal'])
device_humidity_error_range = Decimal(config['Device']['humidity_error_range'])
device_pressure_error_range = Decimal(config['Device']['pressure_error_range'])
device_temperature_error_range = Decimal(config['Device']['temperature_error_range'])
wait_time = int(config['Readings']['wait_time_seconds'])
# Create library object using our Bus I2C port
i2c = busio.I2C(board.SCL, board.SDA)
bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c)
# OR create library object using our Bus SPI port
# spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
# bme_cs = digitalio.DigitalInOut(board.D10)
# bme280 = adafruit_bme280.Adafruit_BME280_SPI(spi, bme_cs)
# change this to match the location's pressure (hPa) at sea level
bme280.sea_level_pressure = Decimal(config['Readings']['location_sea_level_pressure'])
mqtt_config = MQTTConfig(config_file_path='config.ini')
mqtt_client = mqtt.Client()
mqtt_client.on_connect = App.on_connect
mqtt_client.on_disconnect = App.on_disconnect
mqtt_client.on_publish = App.on_publish
mqtt_client.connect(host=mqtt_config.server_name,
port=mqtt_config.server_port,
keepalive=mqtt_config.local_timeout)
mqtt_client.username_pw_set(username=mqtt_config.username,
password=mqtt_config.password)
while True:
temperature = bme280.temperature
pascals = bme280.pressure
kilopascals = pascals / 1000.0
humidity = bme280.humidity
timestamp = datetime.utcnow()
humidity_reading = '''{{
"value": {humidity:.4f},
"value_units": "percent",
"value_error_range": {humidity_error_range:.6f},
"timestamp": "{datetime}Z",
"elevation": {elevation:.4f},
"elevation_units": "{elevation_units}",
"latitude": {latitude:.6f},
"longitude": {longitude:.6f}
}}'''.format(humidity=humidity,
humidity_error_range=device_humidity_error_range,
datetime=timestamp.isoformat(),
elevation=elevation,
elevation_units=elevation_units,
latitude=latitude,
longitude=longitude)
pressure_reading = '''{{
"value": {pressure:.4f},
"value_units": "kPa",
"value_error_range": {pressure_error_range:.6f},
"timestamp": "{datetime}Z",
"elevation": {elevation:.4f},
"elevation_units": "{elevation_units}",
"latitude": {latitude:.6f},
"longitude": {longitude:.6f}
}}'''.format(pressure=kilopascals,
pressure_error_range=device_pressure_error_range,
datetime=timestamp.isoformat(),
elevation=elevation,
elevation_units=elevation_units,
latitude=latitude,
longitude=longitude)
temperature_reading = '''{{
"value": {temperature:.4f},
"value_units": "C",
"value_error_range": {temperature_error_range:.6f},
"timestamp": "{datetime}Z",
"elevation": {elevation:.4f},
"elevation_units": "{elevation_units}",
"latitude": {latitude:.6f},
"longitude": {longitude:.6f}
}}'''.format(temperature=temperature,
temperature_error_range=device_temperature_error_range,
datetime=timestamp.isoformat(),
elevation=elevation,
elevation_units=elevation_units,
latitude=latitude,
longitude=longitude)
(humidity_mqtt_result, humidity_mid) = mqtt_client.publish(topic=mqtt_config.topic_humidity,
payload=humidity_reading,
qos=2,
retain=True)
mqtt_client.loop(timeout=mqtt_config.local_timeout,
max_packets=mqtt_config.max_packets)
(pressure_mqtt_result, pressure_mid) = mqtt_client.publish(topic=mqtt_config.topic_pressure,
payload=pressure_reading,
qos=2,
retain=True)
mqtt_client.loop(timeout=mqtt_config.local_timeout,
max_packets=mqtt_config.max_packets)
(temperature_mqtt_result, temperature_mid) = mqtt_client.publish(topic=mqtt_config.topic_temperature,
payload=temperature_reading,
qos=2,
retain=True)
mqtt_client.loop(timeout=mqtt_config.local_timeout,
max_packets=mqtt_config.max_packets)
print('MQTT Result Humidity: {humidity_mqtt_result} [mid: {humidity_mid}]'.format(
humidity_mqtt_result=humidity_mqtt_result,
humidity_mid=humidity_mid))
print('MQTT Result Pressure: {humidity_mqtt_result} [mid: {pressure_mid}]'.format(
humidity_mqtt_result=pressure_mqtt_result,
pressure_mid=pressure_mid))
print('MQTT Result Temperature: {temperature_mqtt_result} [mid: {temperature_mid}]'.format(
temperature_mqtt_result=temperature_mqtt_result,
temperature_mid=temperature_mid))
# wait time in seconds
time.sleep(wait_time)
if __name__ == '__main__':
App.main()