WaterDispenserSimulator (Mouse Click)
===
###### tags: `SmartDispenserSimulator`
LB: For Hot tank
MB: For Cold tank
RB: For Warm tank
```
#include<iostream>
#include<math.h>
#include<windows.h>
#include<fstream>
#include<ctime>
#include<string>
#include<graphics.h>
#include<conio.h>
#include<stdio.h>
#include<time.h>
#include<sstream>
using namespace std;
int time1 = 0; //time variable for the hot tank temperature calculation
int time2 = 0; //time variable for the warm tank instantenous temperature calculation
int time3 = 0; //time variable for the cold tank instantenous temperature calculation
int powersaving; // powersaving flag for power saving mode of the dispenser
/*
CH_T: Current temperature of the hot warm
CW_T: Current temperature of the warm tank
CC_T: Current temperature of the cold tank
IH_T: Intermediate temperature of the hot tank (for the intercept on the axis)
IW_T: Intermediate temperature of the warm tank (for the intercept on the axis)
IC_T: Intermediate temperature of the cold tank (for the intercept on the axis)
U_SH_T: Setting temperature of the hot tank
L_SH_T: Setting temperature of the hot tank
U_SC_T: Setting temperature of the hot tank
L_SC_T: Setting temperature of the hot tank
SW_T: Starting temperature of the warm tank
currentvol_H: Real-time volume of the hot tank
currentvol_W: Real-time volume of the warm tank
currentvol_C: Real-time volume of the cold tank
M_W: Input water flow rate
left: Specify the left margin on the graphic window
right: Specify the right margin on the graphic window
bottom: Specify the bottom margin on the graphic window
toph: Specify the heater water level in the graphic window
topw: Specify the warm water level in the graphic window
topc: Specify the cold water level in the graphic window
V_H: Total volume of the hot tank
V_W: Total volume of the warm tank
V_C: Total volume of the cold tank
k_H: Conductivity constant for the hot tank
k_W: Conductivity constant for the warm tank
k_C: Conductivity constant for the cold tank
refillingcount: The time for the water to refill the tank
time_refill_warm: The period during the refilling which makes the warm tank temperature drop
refilling: Flag for refilling or not refilling
heating: Flag for heating
cooling: Flag for cooling
Volumeuse: Variable to keep a record of the volume of water used
timet: Total time taken combined for all the time for water in each tank
*/
int count = 0; // A variable to control if want to execute the program for some minutes only
class WaterDispenser
{
private:
float CH_T,SH_T,CW_T,SW_T,CC_T,SC_T;
float U_SH_T,L_SH_T,U_SC_T,L_SC_T;
float CV_H,CV_C,CV_W,currentvol_H,currentvol_W,currentvol_C;
float k_H,k_W,k_C;
int left, right, bottom;
float toph,topw,topc;
int V_H, V_C, V_W;
float IH_T, IW_T, IC_T;
int refillingcount;
int time_refill_warm;
int refilling_warm, ttemp_warm;
int refilling;
int heating, cooling;
int counter;
float volumeuse;
float timet;
public:
WaterDispenser() //constructor for initializing default constant variables
{
left = 100;
toph = 100;
topw = 150;
topc = 175;
right = 200;
bottom = 200;
V_H = 22;
V_W = 10;
V_C = 4;
time_refill_warm = 0;
refilling_warm = 0;
refilling = 0;
heating = 0;
cooling = 0;
powersaving = 0;
counter = 0;
volumeuse = 0;
timet = 0;
}
void PowerSaver()
{
string s2 = "Tue Jun 11 14:48"; //Change the variables here to set the power saving starting time
string s3 = "Tue Jun 11 14:50";//Change the values here to set the power saving stop time
time_t tt; //Time structure variable to get the current time
struct tm * ti;
time(&tt);
string s1;
ti = localtime(&tt);//obtain the current time of the system
s1 = asctime(ti);
s1 = s1.substr(0,16);
if(s2.compare(s1) == 0)
{
powersaving = 1;
cout<<"Power Saving On"<<endl;
Sleep(500);
}
else if(s3.compare(s1) == 0)
{
powersaving = 0;
cout<<"Power Saving Off"<<endl;
}
}
void InputParameters() //function to take the input of the values of the tank
{
ifstream ip("parameter.csv"); //parameter.csv is a file generated by the python code to keep all the parameters
SW_T = 34.1;
if(!ip.is_open()) // Open the csv file
cout<< "Error"<<endl; // if not open then show error
string hotlower, hotupper, coldlower, coldupper, kh, kw, kc; // strings for reading the different parameters
while(ip.good()) // Reading till the end of the file to get all the parameters
{
getline(ip,hotlower,',');
getline(ip,hotupper,',');
getline(ip,coldlower,',');
getline(ip,coldupper,',');
getline(ip,kh,',');
getline(ip,kw,',');
getline(ip,kc,'\n');
istringstream(hotlower)>>L_SH_T; // converting the strings to float to get the data
istringstream(hotupper)>>U_SH_T;
istringstream(coldlower)>>L_SC_T;
istringstream(coldupper)>>U_SC_T;
istringstream(kh)>>k_H;
istringstream(kw)>>k_W;
istringstream(kc)>>k_C;
}
currentvol_H = V_H; //Set the volume to full
CH_T = U_SH_T; // Set the current temperature to the setting temperature
IH_T = CH_T; // Intermediate temperature also become equal to the setting temperature
cout<<L_SH_T<<" = Heat start temperature,"<<endl<<U_SH_T<<" = Heat stop temperature,"<<endl<<L_SC_T<<" = Cool stop temperature,"<<endl<<U_SC_T<<" = Cool start temperature,"<<endl<<k_H<<" = Hot tank Conductivity,"<<endl<<k_W<<" = Warm Tank Conductivity,"<<endl<<k_C<<" = Cold tank Conductivity"<<endl;
}
void hottankrefill()
{
int time_refill = 0; //set the time to zero at the beginning
int ttemp = CH_T; // temperature at the time of refilling
refillingcount = ceil((V_H-currentvol_H)/1.3); // The time calculation for the refilling period
//refilling_warm = 1;
refilling = 1; // set the refilling flag = 1
while(refillingcount--) // the loop where the refilling happens
{
CH_T = -1.2029*time_refill + ttemp; // The refilling temperature drop equation
time_refill = time_refill + 1; // updating the time interval
InstantenousTemperatureWarm();
InstantenousTemperatureCooler();
WriteFile();
}
refilling = 1;
//refilling_warm = 0;
currentvol_H = V_H;
}
void InstantenousTemperatureHeater() //calculate the instantenous temperature of the heater
{
time1 = time1 + 1; //increment the time by 5 seconds everytime to get real time data
float temp;
if(refilling == 1 && powersaving == 0)
{
int ttemp = CH_T;
int time_refill = 0;
while(CH_T < U_SH_T) //calculating the temperature when the tank is heating after refilling
{
CH_T = 0.6059*time_refill + ttemp;
time_refill = time_refill + 1;
heating = 1;
refilling = 0;
refilling_warm = 0;
InstantenousTemperatureWarm();
InstantenousTemperatureCooler();
WriteFile();
}
IW_T = CW_T;
heating = 0;
//refilling_warm = 0;
time1 = 0;
}
else // calculating the temperature during the heat loss
{
temp=((IH_T) + (k_H*time1)); //temperature calculation according to equation 1
cout<<"The instantenous temperature of heater is "<<temp<<endl;
CH_T = temp; //updating the real time temperature
}
if(powersaving == 0) // heating will take place only if the power saving is off
{
if(CH_T < (L_SH_T))
{
cout<< "Start the heater"<<endl;
time1 = 0;
while(CH_T < (U_SH_T))
{
heating = 1;
time1 = time1 + 1;
CH_T = 0.71*time1 + temp;
cout<<CH_T<<endl;
InstantenousTemperatureWarm();
InstantenousTemperatureCooler();
WriteFile();
}
IH_T = CH_T;
heating = 0;
time1 = 0;
}
}
}
void buttonpresshot(float vol) // Function call for the hot tank button pressed
{
volumeuse = volumeuse + vol;
currentvol_H = currentvol_H - vol; //decrease the volume of the tank when hot water is taken out
}
void WarmTankRefill()
{
currentvol_W = V_W; //Warm tank is refilled hence the volume is updated
IW_T = SW_T;
}
void InstantenousTemperatureWarm() //Instantenous tempearture calculation function for the warm tank
{
time2 = time2 + 1; //time update to get the instantenous temperature
ttemp_warm = CW_T;
if(powersaving)
{
float temp= (-(0.0097*time2) + IW_T);
CW_T = temp; //updating the temperature in each loop
cout<<"Temperature in Power Saving Warm"<<CW_T<<endl;
}
else
{
if(refilling) // heat loss in the warm tank during the refilling process
{
CW_T = -0.7143*time_refill_warm + ttemp_warm;
//cout<<"Inside Refilling "<<CW_T<<endl;
time_refill_warm = time_refill_warm + 1;
IW_T = CW_T;
}
else
{
time_refill_warm = 0;
float temp= ((k_W*time2) + IW_T);
CW_T = temp; //updating the temperature in each loop
cout<<"The instantenous temperature in the warm tank is "<<temp<<endl;
}
}
}
void buttonpresswarm(float vol) // Function call for warm button is pressed
{
volumeuse = volumeuse + vol;
currentvol_W = currentvol_W - vol; //update volume when warm water is taken out
currentvol_H = currentvol_H - vol;
CW_T = (((currentvol_W*CW_T)+(vol*CH_T))/(vol + currentvol_W));
IW_T = CW_T;
currentvol_W = V_W;
if(currentvol_W <= 0) //The volume of water in the warm tank is completed
{
currentvol_W = V_W; //fill the water in the warm tank from the hot tank
topw = 150;
currentvol_H = currentvol_H - V_W;
toph = toph + 45.4;
}
if(currentvol_H<0) //if the water in the hot tank is also completed
{
currentvol_H = V_H; //fill the water in the hot tank from the mains supply
toph = 100;
}
}
void GUIhottank(float l, int m) //making the GUI for the three tanks
{ //c: Volume of water taken out
int gd = DETECT, gm; //initializing the graphic window
initgraph(&gd, &gm, "C:\\TC\\BGI"); //calling the window BGI graphic window to start the graphi window
rectangle(left, 100, right, bottom); // draw a rectangle of the specified size to show the hot water tank
float volume, volume1, volume2; //volume of water taken from each tank
float timeh, timew, timec;
setcolor(RED); //color of the line
setlinestyle(0,0,4); // setting the thickness of the line as 4 pixels
line(100, toph, 200, toph); // draw the line with the co-ordinates as parameters
setfillstyle(SOLID_FILL,RED);
bar(left, 300, right, 400);
setcolor(WHITE); //set the text color
outtextxy(150,350,"LB");
char a[150]; // character array to store the numeric values to be printed to the GUI
sprintf(a,"T: %0.1f \t V:%0.1f/22", CH_T, currentvol_H); // Printing the current temperature and volume to the character array
outtextxy(105,210,a); //printing the character array to the graphic window of the GUI
setlinestyle(0,0,1);
rectangle(left + 200, 150, right + 200, bottom);
setcolor(BLUE);
setlinestyle(0,0,4);
line(300, topw, 400, topw);
setfillstyle(SOLID_FILL,BLUE);
bar(left + 200, 300, right + 200, 400);
setcolor(WHITE);
outtextxy(350,350,"RB");
setcolor(WHITE);
char b[150];
sprintf(b,"T: %0.2f \t V:%0.1f/10", CW_T, currentvol_W);
outtextxy(305,210,b);
setlinestyle(0,0,1);
rectangle(left + 400, 175, right + 400, bottom);
setcolor(CYAN);
setlinestyle(0,0,4);
line(500, topc, 600, topc);
setfillstyle(SOLID_FILL,CYAN);
bar(left + 400, 300, right + 400, 400);
setcolor(WHITE);
outtextxy(550,350,"MB");
setcolor(WHITE);
char c[150];
sprintf(c,"T: %0.2f \t V:%0.1f/4.0", CC_T, currentvol_C);
outtextxy(505,210,c);
Sleep(2000); //Wait for 5 seconds to display the GUI
volume = 0; //initializing the variables to zero
volume1 = 0;
volume2 = 0;
timeh = 0;
timec = 0;
timew = 0;
// switch(m) //switch to the case which the button was pressed
// {
// case 1:
// volume = l;
// timeh = volume/0.028; // time for which hot tank button was pressed
// toph = toph + (4.54*volume);// each segment is represented by (100/22) = 4.54. Hence, if 1 L is taken out line reduces by 4.54
// buttonpresshot(volume);
// break;
// case 2:
// volume1 = l;
// timew = volume1/0.029; // time for which the warm tank button was pressed
// toph = toph + (4.54*volume1);
// buttonpresswarm(volume1);
// break;
// case 3:
// volume2 = l;
// timec = volume2/0.023;
// toph = toph + (4.54*volume2);
// buttonpresscold(volume2);
// break;
// }
/* The Mouse Button Part */
if(GetAsyncKeyState(VK_LBUTTON))
{
cout<<"Enter the amount of water needed"<<endl;
cin>>volume;
timeh = volume/0.028; // time for which hot tank button was pressed
toph = toph + (4.54*volume);// each segment is represented by (100/22) = 4.54. Hence, if 1 L is taken out line reduces by 4.54
buttonpresshot(volume);
}
if(GetAsyncKeyState(VK_RBUTTON))
{
cout<<"Enter the amount of water needed"<<endl;
cin>>volume1;
timew = volume1/0.029; // time for which the warm tank button was pressed
toph = toph + (4.54*volume1);
buttonpresswarm(volume1);
}
if(GetAsyncKeyState(VK_MBUTTON))
{
cout<<"Enter the amount of water needed."<<endl;
cin>>volume2;
timec = volume2/0.023;
toph = toph + (4.54*volume2);
buttonpresscold(volume2);
}
timet = timet + timew + timec + timeh;
if(timet > 100) // if greater than 100seconds show a message and start to refill
{
cout<<"Water will auto refill."<<endl;
hottankrefill();
timet = 0;
}
if(refilling)
{
toph = 100; //reset to the default value
currentvol_H = V_H;
}
closegraph(); //Close the graph to avoid crashing of the program
}
void coldtankrefill()
{
currentvol_C = V_C; //refilling the cold tank
IC_T = (L_SC_T);
}
void InstantenousTemperatureCooler() //Calculating the instantenous temperature for the cooler
{
time3 = time3 + 1;
float temp = ((IC_T) + k_C*time3);
cout<<"The instantenous temperature of cold water is "<<temp<<endl;
CC_T = temp; //updating the instantenous temperature
if(powersaving == 0) // cooling is on when power saving is off
{
if(CC_T >= (U_SC_T))
{
cout<<"The cooler is on "<<endl;
time3 = 0;
while(CC_T > (L_SC_T))
{
cooling = 1;
CC_T = (-0.8929*time3) + 22.662;
time3 = time3 + 1;
InstantenousTemperatureHeater();
InstantenousTemperatureWarm();
WriteFile();
}
cooling = 0;
IC_T = CC_T;
time3 = 0;
}
}
}
void buttonpresscold(float vol) // Function call for cold tank button press
{
volumeuse = volumeuse + vol;
currentvol_C = currentvol_C - vol; //updating the volume of the tank when cold water is taken out
currentvol_W = currentvol_W - vol;
currentvol_H = currentvol_H - vol;
CC_T = (((currentvol_C*CC_T)+(vol*CW_T))/(vol + currentvol_C));
IC_T = CC_T;
CW_T = (((currentvol_W*CW_T)+(vol*CH_T))/(vol + currentvol_W));
IW_T = CW_T;
currentvol_C = V_C;
currentvol_W = V_W;
}
void WriteFile() //for writing the data into the text file.
{
count++;
ofstream myfile;
long int sysTime = time(0);
string pi;
stringstream ss;
ss<<sysTime;
pi = ss.str();
string s2;
s2.append(pi);
s2.append("000");
//cout<<s2<<endl;
//Sleep(2000);
cout<<count<<endl;
time_t tt;
struct tm * ti;
time(&tt);
ti = localtime(&tt);
char buffer[200];
strftime(buffer,200,"%Y-%m-%d %H:%M:%S",ti);
myfile.open("Simulator_MA_04.csv",ios::out|ios::app); //open a new text file for operations
if(counter == 0)
{
myfile<<"UploadTime,TimeStamp,SavingPower,HotTemp,HotTank_Vol,WarmTemp,WarmTank_Vol,ColdTemp,ColdTank_Vol,Usage_L,Heating,Cooling,Refilling"<<endl;
counter++;
}
myfile<<buffer<<","<<s2<<","<<powersaving<<","<<CH_T<<","<<currentvol_H<<","<<CW_T<<","<<currentvol_W<<","<<CC_T<<","<<currentvol_C<<","<<volumeuse<<","<<heating<<","<<cooling<<","<<refilling<<endl; //write the current water temperature and the current volume of water to the file.
myfile.close();
}
};
int main()
{
int buttonpress = 0; //Flag to know which button is pressed
WaterDispenser WD; //object of the class for operations
int c = 1;
//ifstream ip("Test1.csv"); //The output of the pythin program which gives the amount of water consumed and the tank from which it is consumed
//if(!ip.is_open()) // if file not exist show error
//cout<< "Error"<<endl;
string volumeuse;
string value;
while(1)
{
//while(ip.good())
//{
WD.PowerSaver();
if(c==1) //refilling will take place manually or automatically depending upon the user input
{
WD.InputParameters();
WD.WarmTankRefill();
WD.coldtankrefill();
// timet = 0;
c = 0;
}
//if(timet > 157)
//{
// WD.hottankrefill();
// timet = 0;
//}
WD.InstantenousTemperatureHeater(); //getiing the instantenous temperature in each loop
WD.InstantenousTemperatureWarm();
WD.InstantenousTemperatureCooler();
if(powersaving == 0)
{
float i_dec = 0;
float i_hex = 0;
//getline(ip,volumeuse,',');
//getline(ip,value,'\n');
//istringstream(volumeuse)>>i_dec;
//istringstream(value)>>i_hex;
WD.GUIhottank(i_dec, i_hex);
}
WD.WriteFile(); // Store the dispenser status at every minute to the csv file
//}
}
cout<<"Done parsing the file"<<endl;
exit(0);
cout<<"Done please exit"<<endl;
return 0;
}
```