#include <I2CKeyPad.h>
#include <LiquidCrystal_I2C.h>
#include <PubSubClient.h>
#include <WiFi.h>
#include "RTClib.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include <DHT.h>
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
#define deltaTime(val) (millis() - val)
I2CKeyPad keyPad(0x38);
char keypad_layout[19] = "123A456B789C*0#DNF"; // N = NO_KEY, F = FAILED
LiquidCrystal_I2C lcd(0x27, 16, 2); // Change 0x27 to the correct I2C address for your LCD
// Just to avoid spamming
unsigned long lastKeyPress = 0;
unsigned long keyDelay = 200;
char message_buff[100];
int InverterOn = 18;
int WaterPump = 19;
int PollinatorMotor = 21;
int pinState = 0;
#define ONE_WIRE_BUS 22
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
#define CYCLES 3
#define TARGET_HOUR 10
#define TARGET_MINUTE 50
#define OPEN_DURATION 2
#define CYCLE_DELAY 3
#define DHTPIN 23
#define DHTTYPE DHT22
void sensorRead();
DHT dht(DHTPIN, DHTTYPE);
/// Relay 1 and 2 ///
int RmotorUp = 13; // Starter motor relay right
int RmotorDown = 14; // Starter motor relay right
/// Relay 3 and 4 ///
int LmotorUp = 16; // Starter motor relay right
int LmotorDown = 17; // Starter motor relay right
const char *WIFI_SSID = "Wokwi-GUEST";
const char *WIFI_PWD = "";
const char* mqtt_server = "broker.hivemq.com";
//const uint16_t MQTT_PORT = 1883;
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
float temp = 0;
float hum = 0;
boolean force = 0;
boolean is_cooling = false;
boolean cooling_enabled = false;
boolean connected_t_server = false;
String readString;
int test = 3;
//int LDR = A15; // LDR sensor is connected to analog in 5
int PIRstate = 0; // variable for PIR sensor status
float photocell = 0; // variable for photocell (LDR) analog value
char c = 0; // received data
char command[2] = "\0"; // command
int BH1750_Device = 0x23; // I2C address for light sensor
int iCheck = 0; // iCheck = 0 for Lux, iCheck = 1 for Foot-Candles
unsigned int Lux, Scaled_FtCd;
float FtCd, Wattsm2;
int IntPin = 0; // See more at: http://embedded-lab.com/blog/?p=7558#sthash.LIIJENcR.dpuf
int soil = 0;
unsigned long lastD = 0;
unsigned long refresh_ts = -1;
unsigned long last_connect = -1;
unsigned long pump_timing = -1;
boolean pump_state = 0;
#define PUMP_OFF_DURATION 360
#define PUMP_ON_DURATION 240
/*void SetupMqtt()
{
mqttClient.setServer(MQTT_SERVER, MQTT_PORT);
// set the callback function
mqttClient.setCallback(CallbackMqtt);
}*/
unsigned long time1;
int seq = 0;
int x = -1;
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
String clientId = "ESP32Client-";
clientId += String(random(0xffff), HEX);
if (client.connect(clientId.c_str())) {
Serial.println("Connected");
client.publish("/ThinkIOT/Publish", "Welcome");
client.subscribe("/ThinkIOT/Subscribe");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}}
}
void ConnectToWiFi()
{
Serial.print("Connecting to WiFi ");
Serial.println(WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PWD, 6);
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(500);
}
Serial.print("\nConnected to ");
Serial.println(WIFI_SSID);
}
void setup() {
Serial.begin(9600);
//ConnectToWiFi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
/*if (!keyPad.begin()) {
Serial.print("Cannot connect to I2C keypad.\n");
while (1);
}*/
keyPad.loadKeyMap(keypad_layout);
lcd.init();
lcd.backlight(); // You can remove this line if your LCD doesn't have backlight control
lcd.setCursor(0, 0);
lcd.print("Press a key:");
//lcd.setCursor(0, 3);
// lcd.print("HAVE A NICE DAY:");
lcd.setCursor(0, 3);
lcd.print("PROJECT BY ARVIND:");
pinMode(InverterOn, OUTPUT);
digitalWrite(InverterOn, LOW);
pinMode(RmotorUp, OUTPUT);
pinMode(RmotorDown, OUTPUT);
pinMode(LmotorUp, OUTPUT);
pinMode(LmotorDown, OUTPUT);
digitalWrite(RmotorUp, LOW);
digitalWrite(RmotorDown, LOW);
digitalWrite(LmotorUp, LOW);
digitalWrite(LmotorDown, LOW);
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, lets set the time!");
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
sensors.begin();
dht.begin();
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
if (keyPad.isPressed() && deltaTime(lastKeyPress) > keyDelay) {
lastKeyPress = millis();
char key = keyPad.getChar();
//Serial.println( String(key));
lcd.setCursor(0, 1);
// lcd.print("Pressed: " + String(key));
check(key);
DateTime now = rtc.now();
}
//
// Makes the code run faster
delay(10);
}
void check(char key) {
if (key) // Check for a valid key.
{
switch (key) {
case '1':
Serial.println(key);
lcd.clear();
lcd.print("LmotorUp");
digitalWrite(LmotorDown, LOW);
delay(100);
digitalWrite(LmotorUp, HIGH);
client.publish("/openhab/thermokipio/command/fan", "1");
break;
case '2':
Serial.println(key);
lcd.clear();
lcd.print("LmotorDown");
digitalWrite(LmotorUp, LOW);
delay(100);
digitalWrite(LmotorDown, HIGH);
break;
case '3':
Serial.println("RmotorOFF");
lcd.clear();
lcd.print("MotorOFF");
digitalWrite(RmotorUp, LOW);
digitalWrite(RmotorDown, LOW);
digitalWrite(LmotorUp, LOW);
digitalWrite(LmotorDown, LOW);
break;
case '4':
// Serial.print("Opening Left");
Serial.println("RmotorUp");
lcd.clear();
lcd.print("RmotorUp");
digitalWrite(RmotorDown, LOW);
delay(100);
digitalWrite(RmotorUp, HIGH);
break;
case '5':
Serial.println(key);
lcd.clear();
lcd.print("RmotorDown");
digitalWrite(RmotorUp, LOW);
delay(100);
digitalWrite(RmotorDown, HIGH);
break;
case '*':
Serial.println(key);
digitalWrite(InverterOn, HIGH);
client.publish("/openhab/thermokipio/command/fan", "1");
client.publish("/openhab/thermokipio/command/fan", "0");
break;
case '6':
digitalWrite(InverterOn, LOW);
break;
case '7':
//digitalWrite(WaterPump, LOW);
break;
case '8':
// digitalWrite(WaterPump, LOW);
break;
//default:
// Serial.print(key);
}
}
}
void cooling() {
DateTime now = rtc.now();
if (is_cooling) {
if (pump_timing <= now.unixtime()) {
pump_timing = now.unixtime();
if (pump_state)
{
digitalWrite(WaterPump, LOW);
client.publish("openhab/thermokipio/command/pump", "0");
client.publish("openhab/thermokipio/command/pump/state", "0");
Serial.print("pumpoff ");
//Serial.println();
Serial.print(now.minute(), DEC);
pump_timing += PUMP_OFF_DURATION;
}
else
{
digitalWrite(WaterPump, HIGH);
client.publish("openhab/thermokipio/command/pump", "1");
client.publish("openhab/thermokipio/command/pump/state", "1");
Serial.print("pumpon ");
//Serial.println();
Serial.print(now.minute(), DEC);
pump_timing += PUMP_ON_DURATION;
}
pump_state = !pump_state;
}
}
if (cooling_enabled && (now.hour() >= 7 && now.hour() < 18 && !is_cooling)) {
//Serial.print(" Open ");
float t = dht.readTemperature();
float t1 = sensors.getTempCByIndex(0);
//t=30;
if (t > 29) {
//Inverter On
digitalWrite(InverterOn, LOW);
client.publish("openhab/thermokipio/command/fan", "1");
client.publish("openhab/thermokipio/command/fan/state", "1");
//Pump On
digitalWrite(WaterPump, HIGH);
client.publish("openhab/thermokipio/command/pump", "1");
client.publish("openhab/thermokipio/command/pump/state", "1");
//Serial.print(now.minute(), DEC);
pump_state = 1;
pump_timing = now.unixtime() + 300;
startSeq(1);
is_cooling = true;
}
}
if (now.hour() >= 18 || !cooling_enabled) {
//Inverter off
digitalWrite(InverterOn, HIGH);
client.publish("openhab/thermokipio/command/fan", "0");
client.publish("openhab/thermokipio/command/fan/state", "0");
//Pump off
digitalWrite(WaterPump, LOW);
client.publish("openhab/thermokipio/command/pump", "0");
client.publish("openhab/thermokipio/command/pump/state", "0");
//Serial.print(" Open ");
//x = 1;
startSeq(0);
is_cooling = false;
}
}
//Windows opening/closing sequence
void startSeq(int nSeq) {
x = nSeq;
if (x >= 0 && !seq) {
//Serial.println("Closing window right");
//Right motor down
check('1' + 2 * x);
time1 = millis();
seq = 1;
}
}
void check_seq(int offset) {
unsigned long cur_time = millis();
if ((cur_time - time1) > 180000) {
if (seq == 1) {
//Serial.println("stoping window right");
check('*');
//digital write off
seq = 2;
//Serial.println("opening window left");
//digital write on
check('1' + 2 * offset + 1);
time1 = cur_time;
}
else if (seq == 2) {
//Serial.println("stoping window left");
check('*');
seq = 0;
//digital write off
}
}
}
void trigger_cooling(boolean cooling_state);
void callback(char* topic, byte* payload, unsigned int length) {
int i = 0;
for (i = 0; i < length; i++) {
//Serial.print((char)payload[i]);
message_buff[i] = payload[i];
}
message_buff[i] = '\0';
String msgString = String(message_buff);
if (msgString.equals("FANOFF")) {
client.publish("openhab/thermokipio/command/fan", "0");
client.publish("openhab/thermokipio/command/fan/state", "0");
digitalWrite(InverterOn, HIGH);
}
else if (msgString.equals("FANON")) {
client.publish("openhab/thermokipio/command/fan", "1");
client.publish("openhab/thermokipio/command/fan/state", "1");
digitalWrite(InverterOn, LOW);
}
else if (msgString.equals("PUMPON")) {
client.publish("openhab/thermokipio/command/pump", "1");
client.publish("openhab/thermokipio/command/pump/state", "1");
digitalWrite(WaterPump, HIGH);
}
else if (msgString.equals("PUMPOFF")) {
client.publish("openhab/thermokipio/command/pump", "0");
client.publish("openhab/thermokipio/command/pump/state", "0");
digitalWrite(WaterPump, LOW);
}
else if (msgString.startsWith("WINDOW_PERC_")) {
// WINDOW_PERC_3
// WINDOW_PERC_3
char c = msgString[msgString.length() - 1];
// check(c);
}
else if (msgString.startsWith("WINDOW")) {
// WINDOW_1
// WINDOW_*
char c = msgString[msgString.length() - 1];
check(c);
}
else if (msgString.equals("COOLING_ON")) {
client.publish("openhab/thermokipio/command/Cooling", "1");
client.publish("openhab/thermokipio/command/Cooling/state", "1");
trigger_cooling(true);
}
else if (msgString.equals("COOLING_OFF")) {
client.publish("openhab/thermokipio/command/Cooling", "0");
client.publish("openhab/thermokipio/command/Cooling/state", "0");
trigger_cooling(false);
}
Serial.println();
}
void trigger_cooling(boolean cooling_state) {
cooling_enabled = cooling_state;
}