Major update/rewrite/recombine to get SSDP, and GrowController UI and application shell.

This commit is contained in:
David
2021-10-25 23:46:03 +00:00
parent c47c37a891
commit 4597350845
52 changed files with 4981 additions and 4990 deletions

246
Firmware/PlantModel.cpp Normal file
View File

@@ -0,0 +1,246 @@
//
//
// PlantModel
//
//
#include "ProjGlobals.h"
#include "PlantModel.h"
#include "WiFiStateHandler.h"
#include "Utility.h"
PlantData_T plant; /// This keeps track of everything relevant to this system
String OnOffText(bool isOn) {
if (isOn)
return String("On");
else
return String("Off");
}
String DrumStateText(DrumState_E state) {
switch (state) {
case DrumIsOpen:
return String("Open");
case DrumIsClosed:
return String("Closed");
case DrumIsMoving:
return String("Moving");
default:
return String("Error");
}
}
String DrumMotorText(DrumMotor_E state) {
switch (state) {
case DrumOff:
return String("Stopped");
case DrumCW:
return String("CW Rotation");
case DrumCCW:
return String("CCW Rotation");
default:
return String("Error");
}
}
String DrumOpenText(bool isOpen) {
if (isOpen)
return String("Open");
else
return String("not open");
}
String DrumClosedText(bool isClosed) {
if (isClosed)
return String("Closed");
else
return String("not closed");
}
String WaterInTankText(bool waterInTank) {
if (waterInTank)
return String("OK");
else
return String("Empty");
}
// {
// "id": "5c:cf:7f:c0:52:82",
// "name": "3-Way Switch",
// "state": 0,
// "sense": 56,
// "ip": "192.168.1.23",
// "rssi": "-63",
// "countdown": "3:45",
// "uptime": "0:11:45",
// "wifimode": "station"|"ap"
// }
//
void HandleGetState() {
int day, hr, minute, sec;
char _upTime[15]; // 0000.00:00:00\0 + 1 spare
sec = millis() / 1000;
minute = sec / 60;
hr = minute / 60;
day = hr / 24;
if (day)
snprintf(_upTime, sizeof(_upTime), "%dd %d:%02d:%02d", day, hr % 24, minute % 60, sec % 60);
else if (hr)
snprintf(_upTime, sizeof(_upTime), "%d:%02d:%02d", hr, minute % 60, sec % 60);
else
snprintf(_upTime, sizeof(_upTime), "%02d:%02d", minute % 60, sec % 60);
String modeText = (WiFiStateGet() == WFC_JoinedAP) ? "Station" : "Access Point";
String message = "{\n";
message += "\t\"id\": \"" + GetMacString() + "\",\n";
message += "\t\"name\": \"" + wifiConfig.getName() + "\",\n";
message += "\t\"version\": \"" + AP_VERS + "\",\n";
//message += "\t\"state\": " + String(CurrStatus) + ",\n";
//message += "\t\"raw\": " + String(iRaw) + ",\n";
//message += "\t\"sense\": " + String(iRawSum / AVG_RATIO) + ",\n";
message += "\t\"ip\": \""
+ String(WiFi.localIP()[0])
+ "." + String(WiFi.localIP()[1])
+ "." + String(WiFi.localIP()[2])
+ "." + String(WiFi.localIP()[3])
+ "\",\n";
message += "\t\"rssi\": \"" + String(WiFi.RSSI()) + "\",\n";
message += "\t\"uptime\": \"" + String(_upTime) + "\",\n";
message += "\t\"wifimode\": \"" + modeText + "\",\n";
snprintf(_upTime, sizeof(_upTime), "%02u:%02u", plant.SecondsToday/3660, (plant.SecondsToday/60)%60);
message += "\t\"TimeOfDay\": \"" + String(_upTime) + "\",\n";
message += "\t\"Fahrenheit\": \"" + String(plant.Fahrenheit) + "\",\n";
message += "\t\"ChamberTemp_C\": \"" + String(plant.ChamberTemp_C) + "\",\n";
message += "\t\"ChamberHumi\": \"" + String(plant.ChamberHumi) + " % \",\n";
message += "\t\"SoilHeater\": \"" + OnOffText(plant.SoilHeater) + "\",\n";
message += "\t\"SoilTemp_C\": \"" + String(plant.SoilTemp_C) + "\",\n";
message += "\t\"AmbientTemp_C\": \"" + String(plant.AmbientTemp_C) + "\",\n";
message += "\t\"DrumDoorIcon\": \"" + DrumStateText(plant.DrumDoorIcon) + "\",\n";
message += "\t\"DrumOpenSensor\": \"" + DrumOpenText(plant.DrumOpenSensor) + "\",\n";
message += "\t\"DrumClosedSensor\": \"" + DrumClosedText(plant.DrumClosedSensor) + "\",\n";
message += "\t\"DrumMotorStatus\": \"" + DrumMotorText(plant.DrumMotorStatus) + "\",\n";
message += "\t\"DrumMotor_V\": \"" + String(plant.DrumMotor_V) + "\",\n";
message += "\t\"DrumMotor_I\": \"" + String(plant.DrumMotor_I) + "\",\n";
snprintf(_upTime, sizeof(_upTime), "%02u:%02u", plant.DrumMotorOn_sec/60, plant.DrumMotorOn_sec%60);
message += "\t\"DrumMotorOn_sec\": \"" + String(_upTime) + "\",\n";
message += "\t\"WaterInTank\": \"" + String(plant.WaterInTank) + "\",\n";
message += "\t\"WaterMotor_V\": \"" + String(plant.WaterPumpStatus) + "\",\n";
message += "\t\"SoilMoisture_X\": \"" + String(plant.SoilMoisture_X) + "\",\n";
snprintf(_upTime, sizeof(_upTime), "%02u:%02u", plant.WaterCyclePeriod_sec/60, plant.WaterCyclePeriod_sec%60);
message += "\t\"WaterCyclePeriod_sec\": \"" + String(_upTime) + "\",\n";
snprintf(_upTime, sizeof(_upTime), "%02u:%02u", plant.WaterCycleOn_sec/60, plant.WaterCycleOn_sec%60);
message += "\t\"WaterCycleOn_sec\": \"" + String(_upTime) + "\",\n";
snprintf(_upTime, sizeof(_upTime), "%02u:%02u", plant.WaterCycle_sec/60, plant.WaterCycle_sec%60);
message += "\t\"waterCycle\": \"" + String(_upTime) + "\"\n";
//message += "\t\"toggle\": " + String(!digitalRead(SW_TOGGLE)) + ",\n";
//message += "\t\"reset\": " + String(!digitalRead(SW_RESET));
message += "}\n";
server.sendHeader("Access-Control-Allow-Origin", String("*"), true);
server.send(200, "application/json", message);
}
void simulation() {
if (++plant.SecondsToday >= (24*3600)) { // Seconds are advancing really fast for the simulation
plant.SecondsToday -= (24 * 3600);
}
static int lastMinutesToday = -1;
int hoursToday = plant.SecondsToday / 3600;
int minutesToday = plant.SecondsToday / 60;
// Simulate Ambient temp rising and falling
if (lastMinutesToday != minutesToday) {
lastMinutesToday = minutesToday;
Serial.printf("%02u:%02u, Ambient %3.1f\n", hoursToday, minutesToday % 60, plant.AmbientTemp_C);
if (hoursToday < 15) {
// warming part of the day
if (plant.AmbientTemp_C < 45.0) {
plant.AmbientTemp_C += (float)(rand() % 10)/1000.0;
}
} else {
// cooling part of the day
if (plant.AmbientTemp_C > 10.0) {
plant.AmbientTemp_C -= (float)(rand() % 10)/1000.0;
}
}
if (plant.SoilTemp_C > 40.0) {
plant.SoilHeater = false;
} else if (plant.SoilTemp_C < 20.0) {
plant.SoilHeater = true;
}
if (plant.SoilHeater) {
if (plant.SoilTemp_C < 50.0) {
plant.SoilTemp_C += (float)(rand() % 10)/1000.0;
}
} else {
if (plant.SoilTemp_C < plant.ChamberTemp_C) {
plant.SoilTemp_C += (float)(rand() % 10)/1000.0;
} else {
plant.SoilTemp_C -= (float)(rand() % 10)/1000.0;
}
}
if (plant.DrumMotorStatus == DrumCW) {
plant.DrumMotorOn_sec++;
} else if (plant.DrumMotorStatus == DrumCCW) {
plant.DrumMotorOn_sec++;
} else {
plant.DrumMotorOn_sec = 0;
}
if (plant.ChamberTemp_C > 50.0) {
if (!plant.DrumOpenSensor) {
plant.DrumMotorStatus = DrumCW;
if (plant.DrumMotorOn_sec > 50) {
plant.DrumOpenSensor = true;
plant.DrumClosedSensor = false;
}
}
} else if (plant.ChamberTemp_C < 40.0) {
if (!plant.DrumClosedSensor) {
plant.DrumMotorStatus = DrumCW;
if (plant.DrumMotorOn_sec > 50) {
plant.DrumOpenSensor = false;
plant.DrumClosedSensor = true;
}
}
}
if (plant.DrumDoorIcon == DrumIsOpen) {
if (plant.ChamberTemp_C > plant.AmbientTemp_C) {
plant.ChamberTemp_C -= (float)(rand() % 10)/1000.0;
} else if (plant.ChamberTemp_C < plant.AmbientTemp_C) {
plant.ChamberTemp_C += (float)(rand() % 10)/1000.0;
}
} else {
if (plant.ChamberTemp_C > plant.AmbientTemp_C) {
plant.ChamberTemp_C -= (float)(rand() % 5)/1000.0;
} else if (plant.ChamberTemp_C < plant.AmbientTemp_C) {
plant.ChamberTemp_C += (float)(rand() % 20)/1000.0;
}
}
plant.ChamberHumi = (float)(rand() % 73) + 25;
if (++plant.WaterCycle_sec >= plant.WaterCyclePeriod_sec) {
plant.WaterCycle_sec -= plant.WaterCyclePeriod_sec;
}
if (plant.WaterCycle_sec >= plant.WaterCycleOn_sec) {
plant.WaterPumpStatus = false;
}
if (plant.SoilMoisture_X < 60.0 && plant.WaterCycle_sec < plant.WaterCycleOn_sec) {
plant.WaterPumpStatus = true;
}
if (plant.WaterPumpStatus) {
plant.SoilMoisture_X += (float)(rand() % 40)/100.0;
} else {
plant.SoilMoisture_X -= (float)(rand() % 5)/100.0;
}
}
}