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
|
import settings
import sys
import machine
from machine import Pin, I2C, WDT
import network
import time
import struct
import mqtt_as
mqtt_as.MQTT_base.DEBUG = True
from bme280 import BME280
from homie.constants import FALSE, TRUE, BOOLEAN, FLOAT, STRING
from homie.device import HomieDevice
from homie.node import HomieNode
from homie.property import HomieNodeProperty
from uasyncio import get_event_loop, sleep_ms
class WeatherSensor(HomieNode):
def __init__(self, name="bme280", device=None):
super().__init__(id="bme280", name=name, type="sensor")
self.device = device
self.i2c = I2C(scl=Pin(5), sda=Pin(4))
self.bme280 = BME280(i2c=self.i2c)
self.temperature = HomieNodeProperty(
id="temperature",
name="temperature",
unit="°C",
settable=False,
datatype=FLOAT,
default=0,
)
self.add_property(self.temperature)
self.humidity = HomieNodeProperty(
id="humidity",
name="humidity",
unit="%",
settable=False,
datatype=FLOAT,
default=0,
)
self.add_property(self.humidity)
self.pressure = HomieNodeProperty(
id="pressure",
name="pressure",
unit="Pa",
settable=False,
datatype=FLOAT,
default=0,
)
self.add_property(self.pressure)
self.uptime = HomieNodeProperty(
id="uptime",
name="uptime",
settable=False,
datatype=STRING,
default="PT0S"
)
self.add_property(self.uptime)
self.ip = HomieNodeProperty(
id="ip",
name="ip",
settable=False,
datatype=STRING,
default="",
)
self.add_property(self.ip)
self.led = Pin(0, Pin.OUT)
self.online_led = Pin(12, Pin.OUT)
self.online_led.off()
self.last_online = time.time()
self.start = time.time()
print("start time", self.start)
loop = get_event_loop()
loop.create_task(self.update_data())
async def update_data(self):
# wait until connected
for _ in range(60):
print("wait until connected")
await sleep_ms(1_000)
if self.device.mqtt.isconnected():
break
# do 5 measurements to "warm up" the sensor
# for whatever reason the first measurements after poweron are systematically wrong
# I do not understand why
# --- Blaise 2021-07-30
for _ in range(5):
_ = self.bme280.temperature
_ = self.bme280.humidity
_ = self.bme280.pressure
await sleep_ms(500)
# loop forever
while True:
while self.device.mqtt.isconnected():
print("update data")
print(network.WLAN().status())
self.last_online = time.time()
print(1)
self.online_led.on()
print(2)
self.led.value(0) # illuminate onboard LED
self.temperature.data = str(self.bme280.temperature)
self.humidity.data = str(self.bme280.humidity)
self.pressure.data = str(self.bme280.pressure)
self.uptime.data = self.get_uptime()
self.ip.data = network.WLAN().ifconfig()[0]
self.led.value(1) # onboard LED off
print("final")
await sleep_ms(15_000)
while not self.device.mqtt.isconnected():
print("wait for reconnect")
if time.time() - self.last_online > 300: # 5 minutes
machine.reset()
self.online_led.off()
self.led.value(0) # illuminate onboard LED
await sleep_ms(100)
self.led.value(1) # onboard LED off
await sleep_ms(1000)
machine.reset() # if lost connection, restart
def get_uptime(self):
diff = int(time.time() - self.start)
out = "PT"
# hours
if diff // 3600:
out += str(diff // 3600) + "H"
diff %= 3600
# minutes
if diff // 60:
out += str(diff // 60) + "M"
diff %= 60
# seconds
out += str(diff) + "S"
return out
def main():
# homie
print("homie main")
homie = HomieDevice(settings)
homie.add_node(WeatherSensor(device=homie))
homie.run_forever()
if __name__ == "__main__":
main()
|