-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
114 lines (91 loc) · 3.65 KB
/
main.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
import utime
import network
import ubinascii
import ssl
from machine import Pin, Timer # There are 15 timers available, use carefully!
from functools import partial
from irrigation import Irrigation
from umqtt.simple import MQTTClient
from mqtt import Receiver
from password import wifi, hivemq
from config import humidity_config, pump_config, sensor_config
from observable import Observable, ObservableValue, ObservableSum
from pump import Pump
from sensor import MoistureSensor
# Reset the machine every 24h in order to reset caps
TWENTYFOUR_HOURS_IN_MILLISECONDS = 1_000 * 60 * 60 * 24
Timer(-1).init(period=TWENTYFOUR_HOURS_IN_MILLISECONDS, mode=Timer.ONE_SHOT, callback=lambda time: machine.reset())
buzz = Pin(15, Pin.OUT)
pumps = [Pump(Pin(pin, Pin.OUT), name=f'Pump') for pin in range(2, 6)]
leds = [Pin(pin, Pin.OUT, value=0) for pin in range(7, 11)]
buttons = [Pin(pin, Pin.IN, machine.Pin.PULL_UP) for pin in range(11, 15)]
sensors = [MoistureSensor(Pin(pin), name='Moisture', period=1_000, **sensor_config) for pin in range(26, 29)]
def beep(buzz: Pin, duration: int = 100, times = 1):
for i in range(times):
buzz.high()
utime.sleep_ms(duration)
buzz.low()
utime.sleep_ms(duration)
# Manual pump control
def start(button, pump, pin) -> None:
button.irq(trigger=machine.Pin.IRQ_RISING, handler=partial(stop, button, pump))
pump.start()
def stop(button, pump, pin) -> None:
button.irq(trigger=machine.Pin.IRQ_FALLING, handler=partial(start, button, pump))
pump.stop()
# To run pump manually usin buttons. Run while button is pressed.
# WARNING! When the pump is connected to the relay module, it seems to cause transients
# triggering IRQ_FALLING and IRQ_RISING. Thus this cannot be used
for button, pump in zip(buttons, pumps):
pass
#button.irq(trigger=machine.Pin.IRQ_FALLING, handler=partial(start, button, pump))
beep(buzz, times=1)
# WLAN setup
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(wifi.get('ssid'), wifi.get('password'))
wlan.config(pm=0xa11140) # PM_POWERSAVE
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.verify_mode = ssl.CERT_NONE
# MQTT Setup
client = MQTTClient(
client_id=ubinascii.hexlify(machine.unique_id()),
server=hivemq.get('server'),
port=0,
user=hivemq.get('user'),
password=hivemq.get('password'),
keepalive=600,
ssl=ssl_context
)
receiver = Receiver(client)
for i in range(10):
utime.sleep(1)
print('Waiting for WLAN connection...')
if wlan.isconnected():
beep(buzz, times=2)
break
if not wlan.isconnected():
client = None
else:
ip = wlan.ifconfig()[0]
print(f'Connected on {ip}')
status = client.connect()
print(f'MQTT client connected with status {status}')
if status == 0:
beep(buzz, times=3)
else:
client = None
# Irrigation setup
irrigations = []
irrigations.append(Irrigation('Gurka', sensors[0], pumps[0], client, **pump_config, **humidity_config, pump_cap_pin=leds[0]))
irrigations.append(Irrigation('Paprika', sensors[1], pumps[3], client, **pump_config, **humidity_config, pump_cap_pin=leds[3]))
irrigations.append(Irrigation('Hallon', sensors[2], pumps[1], client, **pump_config, **humidity_config, pump_cap_pin=leds[1]))
irrigations.append(Irrigation('Rabarber', sensors[2], pumps[2], client, **pump_config, **humidity_config, pump_cap_pin=leds[2]))
for irr in irrigations:
topic = bytes(f'{irr.name()}/Pump', 'utf-8')
receiver.subscribe(topic, lambda msg, irr=irr: irr._start_pump(int(msg.decode('utf-8')))) # Force capture of irr
while True:
machine.idle()
Observable.next_callback()
if client:
client.check_msg()