Major update/rewrite/recombine to get SSDP, and GrowController UI and application shell.
This commit is contained in:
246
Firmware/PlantModel.cpp
Normal file
246
Firmware/PlantModel.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user