-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathaqua.c
169 lines (135 loc) · 3.31 KB
/
aqua.c
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
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#include "tasmota-devices.h"
#include "tasmota.h"
#include "utils.h"
#include "aqua.h"
#include "mcp.h"
static void set_pump(int value) {
xdebug("AQUA set_pump %d", value);
#ifndef AQUA_MAIN
// tasmota_power(CARPORT, 1, value);
#endif
}
static void set_valve(int valve, int value) {
xdebug("AQUA set_valve %d %d", valve, value);
}
static int get_rain(int valve, int hour) {
int rain = 0;
for (int i = 0; i < ARRAY_SIZE(POTD); i++) {
const aqua_t *a = &POTD[i];
int h = a->hr[hour];
int v = a->v[valve];
if (!h || !v)
continue; // valve not active for this hour
int temp_ok = TEMP >= a->t;
int humi_ok = HUMI <= a->h;
int lumi_ok = LUMI >= a->l;
if (a->l == 0 && a->t == 0) {
// check only humidity
xdebug("AQUA check potd %s for valve=%d rain=%d humi=%d", a->n, valve, a->r, humi_ok);
if (humi_ok)
rain = a->r > rain ? a->r : rain;
} else if (a->l == 0) {
// check humidity and temperature
xdebug("AQUA check potd %s for valve=%d rain=%d humi=%d temp=%d", a->n, valve, a->r, humi_ok, temp_ok);
if (humi_ok && temp_ok)
rain = a->r > rain ? a->r : rain;
} else if (a->t == 0) {
// check humidity and luminousity
xdebug("AQUA check potd %s for valve=%d rain=%d humi=%d lumi=%d", a->n, valve, a->r, humi_ok, lumi_ok);
if (humi_ok && lumi_ok)
rain = a->r > rain ? a->r : rain;
} else {
// check all 3: humidity, temperature and luminousity
xdebug("AQUA check potd %s for valve=%d rain=%d humi=%d lumi=%d temp=%d", a->n, valve, a->r, humi_ok, lumi_ok, temp_ok);
if (humi_ok && lumi_ok && temp_ok)
rain = a->r > rain ? a->r : rain;
}
}
return rain;
}
static void process(int hour) {
xdebug("AQUA sensors temp=%.1f humi=%.1f lumi=%d", TEMP, HUMI, LUMI);
if (TEMP == UINT16_MAX || LUMI == UINT16_MAX || HUMI == UINT16_MAX) {
xlog("AQUA Error no sensor data");
return;
}
for (int v = 0; v < VALVES; v++) {
int rain = get_rain(v, hour);
if (rain) {
xlog("AQUA raining at valve %d for %d seconds", v, rain);
set_valve(v, 1);
set_pump(1);
sleep(rain);
set_valve(v, 0);
}
}
set_pump(0);
}
static void loop() {
int hour = -1;
if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)) {
xlog("Error setting pthread_setcancelstate");
return;
}
// stop pump and close all valves
set_pump(0);
for (int v = 0; v < VALVES; v++)
set_valve(v, 0);
// wait for sensors
sleep(3);
// the AQUA main loop
while (1) {
time_t now_ts = time(NULL);
struct tm *ltstatic = localtime(&now_ts);
// first run on next full hour
if (hour == -1)
hour = ltstatic->tm_hour;
if (hour != ltstatic->tm_hour) {
hour = ltstatic->tm_hour;
process(hour);
}
sleep(60);
}
}
static int init() {
return 0;
}
static void stop() {
}
static int test() {
xlog("module test code");
return 0;
}
int aqua_main(int argc, char **argv) {
set_xlog(XLOG_STDOUT);
set_debug(1);
// no arguments - main loop
if (argc == 1) {
init();
loop();
pause();
stop();
return 0;
}
// with arguments
int c;
while ((c = getopt(argc, argv, "t")) != -1) {
switch (c) {
case 't':
return test();
}
}
return 0;
}
#ifdef AQUA_MAIN
int main(int argc, char **argv) {
return aqua_main(argc, argv);
}
#else
MCP_REGISTER(aqua, 7, &init, &stop, &loop);
#endif