aboutsummaryrefslogtreecommitdiff
path: root/firmware/main.py
blob: f6835b4392d4ccc23d33cba71e6d5376eec2fb55 (plain)
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()