237 lines
6.0 KiB
C++
237 lines
6.0 KiB
C++
#include <Arduino.h>
|
|
#include <Ethernet.h>
|
|
#include <SPI.h>
|
|
#include <PubSubClient.h>
|
|
#include <shiftregister.h>
|
|
#include <string.h>
|
|
#include <ArduinoJson.h>
|
|
|
|
#include "config.h"
|
|
#include "pump.h"
|
|
#include "valve.h"
|
|
|
|
#define BUFFER_SIZE 128
|
|
|
|
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
|
|
|
|
IPAddress ip(192, 168, 13, 0);
|
|
IPAddress subnet(255, 255, 128, 0);
|
|
IPAddress gateway(192, 168, 0, 1);
|
|
IPAddress dns(192, 168, 0, 1);
|
|
IPAddress server(192, 168, 1, 7);
|
|
|
|
// IPAddress ip(192, 168, 178, 202);
|
|
// IPAddress gateway(192, 168, 178, 1);
|
|
// IPAddress subnet(255, 255, 255, 0);
|
|
// IPAddress dns(192, 168, 178, 1);
|
|
// IPAddress server(192, 168, 178, 35);
|
|
// IPAddress server(91, 121, 93, 94);
|
|
|
|
const char mqttUser[] = "kleiax";
|
|
const char mqttPass[] = "p?{$_~5%hBM7wrcFkr55KWr#";
|
|
const char mqttId[] = "bewaesserungArduino123";
|
|
|
|
ShiftRegister reg(RCLK_PIN, SRCLK_PIN, SRSER_PIN, 2);
|
|
Pump pump(SSR_PIN, PRESSURE_PIN, INT_HALL_PIN, STATUS_LED_1_PIN);
|
|
Valve valves(MAX_VALVE_OPEN);
|
|
EthernetClient ethClient;
|
|
PubSubClient client(ethClient);
|
|
// Adafruit_BMP085 bmp;
|
|
|
|
void reconnect();
|
|
void callback(char* topic, byte* payload, unsigned int length);
|
|
void sendPumpStatus();
|
|
void sendValveStatus(uint8_t valveNumber);
|
|
void sendInfo();
|
|
// void sendEnviromentInfo();
|
|
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
Serial.println(F("Arduino Irrigation"));
|
|
|
|
// if (!bmp.begin()) {
|
|
// Serial.println(F("Could not find a valid BMP085 sensor,check wiring!"));
|
|
// while (true);
|
|
// }
|
|
|
|
|
|
pinMode(SROE_PIN, OUTPUT);
|
|
pinMode(SRCLR_PIN, OUTPUT);
|
|
digitalWrite(SROE_PIN, LOW);
|
|
digitalWrite(SRCLR_PIN, HIGH);
|
|
reg.writeByte(0, UINT8_MAX);
|
|
reg.writeByte(1, UINT8_MAX);
|
|
valves.addShiftRegister(®);
|
|
for (uint8_t i = 0; i < VALVE_COUNT; i++)
|
|
valves.add(valvePins[i], true);
|
|
valves.closeAll();
|
|
|
|
client.setServer(server, 1883);
|
|
client.setCallback(callback);
|
|
|
|
Ethernet.begin(mac, ip, dns, gateway, subnet);
|
|
Serial.print(F("Info: "));
|
|
Serial.println(Ethernet.localIP() );
|
|
|
|
// if (Ethernet.begin(mac) == 0) {
|
|
// Serial.println("Failed to configure Ethernet using DHCP");
|
|
// } else {
|
|
// Serial.print(" DHCP assigned IP ");
|
|
// Serial.println(Ethernet.localIP());
|
|
// Serial.println(Ethernet.subnetMask());
|
|
// Serial.println(Ethernet.dnsServerIP());
|
|
// Serial.println(Ethernet.gatewayIP());
|
|
// }
|
|
// // give the Ethernet shield a second to initialize:
|
|
// delay(1000);
|
|
// Serial.print("connecting to ");
|
|
// Serial.println(server);
|
|
|
|
|
|
// Allow the hardware to sort itself out
|
|
delay(1500);
|
|
}
|
|
|
|
void loop() {
|
|
if (!client.connected())
|
|
reconnect();
|
|
client.loop();
|
|
pump.loop();
|
|
valves.loop();
|
|
|
|
static uint32_t lastDataSend = 0;
|
|
if (millis() - lastDataSend > 2000) {
|
|
sendInfo();
|
|
sendPumpStatus();
|
|
// sendEnviromentInfo();
|
|
for (uint8_t i = 0; i < VALVE_COUNT; i++)
|
|
sendValveStatus(i);
|
|
lastDataSend = millis();
|
|
}
|
|
}
|
|
|
|
void callback(char* topic, byte* payload, unsigned int length) {
|
|
if (length > 128) {
|
|
Serial.println(F("Payload to big."));
|
|
return;
|
|
}
|
|
|
|
StaticJsonDocument<128> doc;
|
|
DeserializationError error = deserializeJson(doc, payload, length);
|
|
|
|
if (error) {
|
|
Serial.print("deserializeJson() failed: ");
|
|
Serial.println(error.f_str());
|
|
return;
|
|
}
|
|
|
|
if (doc.containsKey("valve")) {
|
|
uint8_t valveNumber = doc["valve"]["number"];
|
|
uint8_t duration = doc["valve"]["duration"];
|
|
if (duration)
|
|
valves.open(valveNumber, duration);
|
|
else
|
|
valves.close(valveNumber);
|
|
} else if (doc.containsKey("pump")) {
|
|
uint8_t mode = doc["pump"]["mode"];
|
|
uint8_t duration = doc["pump"]["duration"];
|
|
if (mode == Pump::State::OnStupid)
|
|
pump.activateWithoutSecurity();
|
|
else if (mode == Pump::State::clearErrorHelper)
|
|
pump.clearError();
|
|
else if (mode)
|
|
pump.activate(duration);
|
|
else
|
|
pump.stop();
|
|
} else {
|
|
Serial.println(F("Key not found."));
|
|
}
|
|
|
|
// Serial.print("Message arrived [");
|
|
// Serial.print(topic);
|
|
// Serial.print("] ");
|
|
// for (uint8_t i=0;i<length;i++) {
|
|
// Serial.print((char)payload[i]);
|
|
// }
|
|
// Serial.println();
|
|
}
|
|
|
|
void reconnect() {
|
|
char topic[64];
|
|
while (!client.connected()) {
|
|
Serial.print("Attempting MQTT connection...");
|
|
if (client.connect(mqttId, mqttUser, mqttPass)) {
|
|
Serial.println("connected");
|
|
sprintf(topic, "%s/info", mainTopic);
|
|
client.publish(topic,"reconnect");
|
|
sprintf(topic, "%s/order", mainTopic);
|
|
client.subscribe(topic);
|
|
} else {
|
|
Serial.print("failed, rc=");
|
|
Serial.print(client.state());
|
|
Serial.println(" try again in 5 seconds");
|
|
delay(5000);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sendPumpStatus() {
|
|
StaticJsonDocument<96> doc;
|
|
|
|
JsonObject pumpJson = doc.createNestedObject("pump");
|
|
pumpJson["status"] = pump.getStatus();
|
|
pumpJson["duration"] = pump.getRunningTime();
|
|
pumpJson["remaining"] = pump.getRemainingTime();
|
|
pumpJson["pressure"] = pump.getPressure();
|
|
pumpJson["flow"] = pump.getFlow();
|
|
|
|
char buffer[256];
|
|
char topic[64];
|
|
sprintf(topic, "%s/pump", mainTopic);
|
|
size_t n = serializeJson(doc, buffer);
|
|
client.publish(topic, buffer, n);
|
|
}
|
|
|
|
void sendValveStatus(uint8_t valveNumber) {
|
|
StaticJsonDocument<96> doc;
|
|
|
|
JsonObject valve = doc.createNestedObject("valve");
|
|
valve["timeLeft"] = valves.getTimeLeft(valveNumber);
|
|
valve["number"] = valveNumber;
|
|
|
|
char buffer[256];
|
|
char topic[64];
|
|
sprintf(topic, "%s/valve/%d", mainTopic, valveNumber);
|
|
size_t n = serializeJson(doc, buffer);
|
|
client.publish(topic, buffer, n);
|
|
}
|
|
|
|
void sendInfo() {
|
|
StaticJsonDocument<48> doc;
|
|
|
|
JsonObject info = doc.createNestedObject("valve");
|
|
info["uptime"] = millis() / 1000;
|
|
info["opened"] = valves.getNumOfOpen();
|
|
info["max"] = valves.getMaxOpen();
|
|
|
|
char buffer[256];
|
|
char topic[64];
|
|
sprintf(topic, "%s/info", mainTopic);
|
|
size_t n = serializeJson(doc, buffer);
|
|
client.publish(topic, buffer, n);
|
|
}
|
|
|
|
// void sendEnviromentInfo() {
|
|
// StaticJsonDocument<96> doc;
|
|
// JsonObject enviroment = doc.createNestedObject("enviroment");
|
|
|
|
// enviroment["temperature"] = bmp.readTemperature();
|
|
// enviroment["pressure"] = bmp.readPressure();
|
|
|
|
// char buffer[256];
|
|
// char topic[64];
|
|
// sprintf(topic, "%s/info", mainTopic);
|
|
// size_t n = serializeJson(doc, buffer);
|
|
// client.publish(topic, buffer, n);
|
|
// }
|