---
# System prepended metadata

title: WaterDispenserSimulator (Auto)
tags: [SmartDispenserSimulator]

---

WaterDispenserSimulator (Auto)
===

###### tags: `SmartDispenserSimulator`


The cpp file for the Simulator which can work automatically as per the data recorded previously. 

```
#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("WaterDispenser141.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 hottemp;
	string warmtemp;
	string coldtemp;
	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;
				float i_hex; 
				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;
}


```