-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpython_temperature_displayer_mqtt.py
136 lines (91 loc) · 4.01 KB
/
python_temperature_displayer_mqtt.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
130
131
132
133
134
135
136
import os
import asyncio
import json
import asyncio_mqtt
from papirus import PapirusTextPos
with open('config.json', 'r') as file:
config = json.load(file)
broker = config['broker']
display_control_topic = config['display_control_topic']
upper_location_topic = config['upper_location_topic']
lower_location_topic = config['lower_location_topic']
upper_location = {
'temperature': 0,
'humidity': 0,
}
lower_location = {
'temperature': 0,
'humidity': 0,
}
async def subscribe_to_broker():
async with asyncio_mqtt.Client(broker) as client:
async with client.messages() as messages:
topics = [
display_control_topic,
upper_location_topic,
lower_location_topic,
]
for topic in topics:
await client.subscribe(topic)
async for message in messages:
if message.topic.matches(display_control_topic):
await handle_display_message(message)
if message.topic.matches(upper_location_topic) or message.topic.matches(lower_location_topic):
await handle_temperature_message(message)
async def handle_temperature_message(message):
try:
payload = json.loads(message.payload.decode())
if message.topic.matches(upper_location_topic) and 'temperature' in payload and 'humidity' in payload:
upper_location['temperature'] = payload['temperature']
upper_location['humidity'] = payload['humidity']
if message.topic.matches(lower_location_topic) and 'temperature' in payload and 'humidity' in payload:
lower_location['temperature'] = payload['temperature']
lower_location['humidity'] = payload['humidity']
except json.JSONDecodeError as e:
print(e)
async def handle_display_message(message):
try:
payload = json.loads(message.payload.decode())
if 'triggered' in payload and payload['triggered'] is True and is_display_updater_task_running() is not True:
asyncio.create_task(update_display(), name='display_updater')
if 'triggered' in payload and payload['triggered'] is False:
for task in asyncio.all_tasks():
if task.get_name() == 'display_updater':
task.cancel()
PapirusTextPos(False).Clear()
except Exception as e:
print(e)
async def update_display():
# On the very first startup of this script the initial temperature value will be zero,
# so sleep for one second until the real temperature has been read from MQTT
if upper_location['temperature'] == 0 and lower_location['temperature'] == 0:
await asyncio.sleep(1)
while True:
text = PapirusTextPos(False)
font = os.path.dirname(os.path.abspath(__file__)) + '/fonts/pixellium.ttf'
upper_temperature = f"{upper_location['temperature']:.1f}\u00B0"
upper_humidity = f"{upper_location['humidity']:.0f}%"
lower_temperature = f"{lower_location['temperature']:.1f}\u00B0"
lower_humidity = f"{lower_location['humidity']:.0f}%"
text.AddText(upper_temperature, 6, -12, size=112, fontPath=font)
text.AddText(upper_humidity, 180, 26, size=64, fontPath=font)
text.AddText(lower_temperature, 6, 82, size=112, fontPath=font)
text.AddText(lower_humidity, 180, 118, size=64, fontPath=font)
# Once we've got everything in place, _then_ update the entire screen at once
text.WriteAll()
await asyncio.sleep(60)
def is_display_updater_task_running():
task_names = []
for task in asyncio.all_tasks():
task_names.append(task.get_name())
return 'display_updater' in task_names
async def main():
while True:
try:
listen_for_messages = asyncio.create_task(subscribe_to_broker())
print('Started')
await listen_for_messages
except asyncio_mqtt.MqttError as e:
print(e)
await asyncio.sleep(5)
asyncio.run(main())