|
@@ -62,8 +62,29 @@ UniversalTelegramBot bot(TELEGRAM_TOKEN, secured_client);
|
62
|
62
|
unsigned long last_telegram_time = 0;
|
63
|
63
|
String trusted_chat_ids[] = TRUSTED_IDS;
|
64
|
64
|
|
|
65
|
+enum telegram_state {
|
|
66
|
+ BOT_IDLE,
|
|
67
|
+ BOT_ASKED_FERT,
|
|
68
|
+ BOT_ASKED_PLANTS,
|
|
69
|
+ BOT_ASKED_CONFIRM
|
|
70
|
+};
|
|
71
|
+
|
|
72
|
+enum telegram_state bot_state = BOT_IDLE;
|
|
73
|
+String bot_lock = "";
|
|
74
|
+BoolField bot_plants(VALVE_COUNT - 1);
|
|
75
|
+BoolField bot_ferts(PUMP_COUNT);
|
|
76
|
+
|
65
|
77
|
#endif // TELEGRAM_TOKEN
|
66
|
78
|
|
|
79
|
+#ifdef MQTT_HOST
|
|
80
|
+#include <PubSubClient.h>
|
|
81
|
+WiFiClient mqttClient;
|
|
82
|
+PubSubClient mqtt(mqttClient);
|
|
83
|
+unsigned long last_mqtt_reconnect_time = 0;
|
|
84
|
+BoolField mqtt_plants(VALVE_COUNT - 1);
|
|
85
|
+BoolField mqtt_ferts(PUMP_COUNT);
|
|
86
|
+#endif // MQTT_HOST
|
|
87
|
+
|
67
|
88
|
UPDATE_WEB_SERVER server(80);
|
68
|
89
|
WebSocketsServer socket = WebSocketsServer(81);
|
69
|
90
|
SimpleUpdater updater;
|
|
@@ -125,20 +146,13 @@ void wifi_broadcast_state_change(const char *s) {
|
125
|
146
|
bot.sendMessage(trusted_chat_ids[n], "New state: " + String(s), "");
|
126
|
147
|
}
|
127
|
148
|
#endif // TELEGRAM_TOKEN
|
|
149
|
+
|
|
150
|
+#ifdef MQTT_HOST
|
|
151
|
+ mqtt.publish("giessomat", s);
|
|
152
|
+#endif // MQTT_HOST
|
128
|
153
|
}
|
129
|
154
|
|
130
|
155
|
#ifdef TELEGRAM_TOKEN
|
131
|
|
-enum telegram_state {
|
132
|
|
- BOT_IDLE,
|
133
|
|
- BOT_ASKED_FERT,
|
134
|
|
- BOT_ASKED_PLANTS,
|
135
|
|
- BOT_ASKED_CONFIRM
|
136
|
|
-};
|
137
|
|
-
|
138
|
|
-enum telegram_state bot_state = BOT_IDLE;
|
139
|
|
-String bot_lock = "";
|
140
|
|
-BoolField bot_plants(VALVE_COUNT - 1);
|
141
|
|
-BoolField bot_ferts(PUMP_COUNT);
|
142
|
156
|
|
143
|
157
|
unsigned long telegram_update_interval() {
|
144
|
158
|
if (bot_state == BOT_IDLE) {
|
|
@@ -352,6 +366,109 @@ void telegram_hello() {
|
352
|
366
|
}
|
353
|
367
|
#endif // TELEGRAM_TOKEN
|
354
|
368
|
|
|
369
|
+#ifdef MQTT_HOST
|
|
370
|
+
|
|
371
|
+static void mqttCallback(char* topic, byte* payload, unsigned int length) {
|
|
372
|
+ String ts(topic), ps;
|
|
373
|
+ for (unsigned int i = 0; i < length; i++) {
|
|
374
|
+ char c = payload[i];
|
|
375
|
+ ps += c;
|
|
376
|
+ }
|
|
377
|
+
|
|
378
|
+ debug.println("MQTT Rx @ " + ts + ": " + ps);
|
|
379
|
+
|
|
380
|
+ if (ts != "giessomat") {
|
|
381
|
+ debug.println("MQTT: invalid topic");
|
|
382
|
+ return;
|
|
383
|
+ }
|
|
384
|
+
|
|
385
|
+ if (ps == "abort") {
|
|
386
|
+ if (sm_is_idle()) {
|
|
387
|
+ debug.println("MQTT: nothing to abort");
|
|
388
|
+ } else {
|
|
389
|
+ sm_bot_abort();
|
|
390
|
+ debug.println("MQTT: user abort");
|
|
391
|
+ }
|
|
392
|
+ } else {
|
|
393
|
+ if (ps.substring(0, 4) != "auto") {
|
|
394
|
+ debug.println("MQTT: invalid payload");
|
|
395
|
+ return;
|
|
396
|
+ }
|
|
397
|
+
|
|
398
|
+ mqtt_ferts.clear();
|
|
399
|
+ mqtt_plants.clear();
|
|
400
|
+
|
|
401
|
+ String buff;
|
|
402
|
+ bool at_plants = false;
|
|
403
|
+ for (int i = 5; i < ps.length() + 1; i++) {
|
|
404
|
+ if ((i == ps.length()) || (ps[i] == ' ') || (ps[i] == ',')) {
|
|
405
|
+ if (buff != "none") {
|
|
406
|
+ int n = buff.toInt() - 1;
|
|
407
|
+ if (!at_plants) {
|
|
408
|
+ mqtt_ferts.set(n);
|
|
409
|
+ } else {
|
|
410
|
+ mqtt_plants.set(n);
|
|
411
|
+ }
|
|
412
|
+ }
|
|
413
|
+ buff = "";
|
|
414
|
+
|
|
415
|
+ if ((i < ps.length()) && (ps[i] == ' ')) {
|
|
416
|
+ at_plants = true;
|
|
417
|
+ }
|
|
418
|
+ } else {
|
|
419
|
+ buff += ps[i];
|
|
420
|
+ }
|
|
421
|
+ }
|
|
422
|
+
|
|
423
|
+ String s = "MQTT: fertilizers:";
|
|
424
|
+ for (int i = 0; i < PUMP_COUNT; i++) {
|
|
425
|
+ if (mqtt_ferts.isSet(i)) {
|
|
426
|
+ s += " " + String(i + 1);
|
|
427
|
+ }
|
|
428
|
+ }
|
|
429
|
+ debug.println(s);
|
|
430
|
+
|
|
431
|
+ s = "MQTT: plants:";
|
|
432
|
+ for (int i = 0; i < (VALVE_COUNT - 1); i++) {
|
|
433
|
+ if (mqtt_plants.isSet(i)) {
|
|
434
|
+ s += " " + String(i + 1);
|
|
435
|
+ }
|
|
436
|
+ }
|
|
437
|
+ debug.println(s);
|
|
438
|
+
|
|
439
|
+ if (mqtt_plants.countSet() <= 0) {
|
|
440
|
+ debug.println("MQTT: no plants selected");
|
|
441
|
+ return;
|
|
442
|
+ }
|
|
443
|
+
|
|
444
|
+#ifdef FULLAUTO_MIN_PLANT_COUNT
|
|
445
|
+ if (mqtt_plants.countSet() < FULLAUTO_MIN_PLANT_COUNT) {
|
|
446
|
+ debug.println("MQTT: not enough plants selected");
|
|
447
|
+ return;
|
|
448
|
+ }
|
|
449
|
+#endif
|
|
450
|
+
|
|
451
|
+ sm_bot_start_auto(mqtt_ferts, mqtt_plants);
|
|
452
|
+ }
|
|
453
|
+}
|
|
454
|
+
|
|
455
|
+static void mqttReconnect() {
|
|
456
|
+ // Create a random client ID
|
|
457
|
+ String clientId = F("giessomat-");
|
|
458
|
+ clientId += String(random(0xffff), HEX);
|
|
459
|
+
|
|
460
|
+ // Attempt to connect
|
|
461
|
+#if defined(MQTT_USER) && defined(MQTT_PASS)
|
|
462
|
+ if (mqtt.connect(clientId.c_str(), MQTT_USER, MQTT_PASS)) {
|
|
463
|
+#else
|
|
464
|
+ if (mqtt.connect(clientId.c_str())) {
|
|
465
|
+#endif
|
|
466
|
+ mqtt.subscribe("giessomat");
|
|
467
|
+ }
|
|
468
|
+}
|
|
469
|
+
|
|
470
|
+#endif // MQTT_HOST
|
|
471
|
+
|
355
|
472
|
bool wifi_write_database(int duration, const char *type, int id) {
|
356
|
473
|
bool success = false;
|
357
|
474
|
|
|
@@ -874,6 +991,18 @@ void handleRoot() {
|
874
|
991
|
message += F("</p>\n");
|
875
|
992
|
|
876
|
993
|
message += F("<p>\n");
|
|
994
|
+#ifdef MQTT_HOST
|
|
995
|
+ message += F("MQTT: ");
|
|
996
|
+ message += MQTT_HOST;
|
|
997
|
+ message += F(":");
|
|
998
|
+ message += String(MQTT_PORT);
|
|
999
|
+ message += F("\n");
|
|
1000
|
+#else
|
|
1001
|
+ message += F("MQTT not enabled!\n");
|
|
1002
|
+#endif
|
|
1003
|
+ message += F("</p>\n");
|
|
1004
|
+
|
|
1005
|
+ message += F("<p>\n");
|
877
|
1006
|
#ifdef ENABLE_INFLUXDB_LOGGING
|
878
|
1007
|
message += F("InfluxDB: ");
|
879
|
1008
|
message += INFLUXDB_DATABASE;
|
|
@@ -1135,6 +1264,12 @@ void wifi_setup() {
|
1135
|
1264
|
telegram_hello();
|
1136
|
1265
|
#endif // TELEGRAM_TOKEN
|
1137
|
1266
|
|
|
1267
|
+#ifdef MQTT_HOST
|
|
1268
|
+ debug.println("WiFi: initializing MQTT");
|
|
1269
|
+ mqtt.setServer(MQTT_HOST, MQTT_PORT);
|
|
1270
|
+ mqtt.setCallback(mqttCallback);
|
|
1271
|
+#endif // MQTT_HOST
|
|
1272
|
+
|
1138
|
1273
|
server.begin();
|
1139
|
1274
|
MDNS.addService("http", "tcp", 80);
|
1140
|
1275
|
MDNS.addService("http", "tcp", 81);
|
|
@@ -1146,11 +1281,6 @@ void wifi_setup() {
|
1146
|
1281
|
}
|
1147
|
1282
|
|
1148
|
1283
|
void wifi_run() {
|
1149
|
|
- // reset ESP every 6h to be safe
|
1150
|
|
- if ((millis() >= (6UL * 60UL * 60UL * 1000UL)) && (sm_is_idle())) {
|
1151
|
|
- ESP.restart();
|
1152
|
|
- }
|
1153
|
|
-
|
1154
|
1284
|
if (!wifi_ok) {
|
1155
|
1285
|
// nothing to handle
|
1156
|
1286
|
return;
|
|
@@ -1184,6 +1314,15 @@ void wifi_run() {
|
1184
|
1314
|
last_telegram_time = millis();
|
1185
|
1315
|
}
|
1186
|
1316
|
#endif // TELEGRAM_TOKEN
|
|
1317
|
+
|
|
1318
|
+#ifdef MQTT_HOST
|
|
1319
|
+ if (!mqtt.connected() && ((millis() - last_mqtt_reconnect_time) >= MQTT_RECONNECT_INTERVAL)) {
|
|
1320
|
+ last_mqtt_reconnect_time = millis();
|
|
1321
|
+ mqttReconnect();
|
|
1322
|
+ }
|
|
1323
|
+
|
|
1324
|
+ mqtt.loop();
|
|
1325
|
+#endif // MQTT_HOST
|
1187
|
1326
|
}
|
1188
|
1327
|
|
1189
|
1328
|
#endif // PLATFORM_ESP
|